565 lines
24 KiB
C#
565 lines
24 KiB
C#
|
|
using System.Collections.Generic;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEditor.SceneManagement;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.SceneManagement;
|
||
|
|
using UnityEngine.UI;
|
||
|
|
|
||
|
|
public static class Lab2SceneBuilder
|
||
|
|
{
|
||
|
|
private const string ScriptsFolder = "Assets/_Scripts";
|
||
|
|
private const string DataFolder = "Assets/_Data";
|
||
|
|
private const string PrefabsFolder = "Assets/_Prefabs";
|
||
|
|
private const string ScenesFolder = "Assets/_Scenes";
|
||
|
|
private const string MaterialsFolder = "Assets/_Materials";
|
||
|
|
private const string FontsFolder = "Assets/_Fonts";
|
||
|
|
private const string EditorFolder = "Assets/Editor";
|
||
|
|
private const string ScenePath = "Assets/_Scenes/WeaponTest.unity";
|
||
|
|
|
||
|
|
[MenuItem("Tools/Technical Game Design/Lab2/Create Weapon System Scene")]
|
||
|
|
public static void CreateWeaponSystemScene()
|
||
|
|
{
|
||
|
|
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||
|
|
{
|
||
|
|
EditorUtility.DisplayDialog("Lab 2", "Stop Play Mode before generating the scene.", "OK");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
CreateFolders();
|
||
|
|
Font uiFont = CreateOrLoadUbuntuFont();
|
||
|
|
|
||
|
|
Material floorMaterial = CreateMaterial("Floor_Mat", new Color(0.35f, 0.38f, 0.34f));
|
||
|
|
Material wallMaterial = CreateMaterial("Wall_Mat", new Color(0.48f, 0.50f, 0.52f));
|
||
|
|
Material targetMaterial = CreateMaterial("Target_Mat", new Color(0.85f, 0.15f, 0.12f));
|
||
|
|
Material pistolMaterial = CreateMaterial("Pistol_Mat", new Color(0.05f, 0.11f, 0.25f));
|
||
|
|
Material rifleMaterial = CreateMaterial("Rifle_Mat", new Color(0.20f, 0.35f, 0.27f));
|
||
|
|
Material shotgunMaterial = CreateMaterial("Shotgun_Mat", new Color(0.45f, 0.18f, 0.10f));
|
||
|
|
Material smgMaterial = CreateMaterial("SMG_Mat", new Color(0.35f, 0.35f, 0.38f));
|
||
|
|
Material muzzleMaterial = CreateMaterial("MuzzleFlash_Mat", new Color(1f, 0.62f, 0.08f));
|
||
|
|
Material hitMaterial = CreateMaterial("HitEffect_Mat", new Color(1f, 0.95f, 0.25f));
|
||
|
|
|
||
|
|
GameObject muzzleFlashPrefab = CreateEffectPrefab("MuzzleFlashPrefab", muzzleMaterial, new Vector3(0.16f, 0.16f, 0.16f));
|
||
|
|
GameObject hitEffectPrefab = CreateEffectPrefab("HitEffectPrefab", hitMaterial, new Vector3(0.12f, 0.12f, 0.12f));
|
||
|
|
|
||
|
|
WeaponData pistolData = CreateWeaponData(
|
||
|
|
"PistolData",
|
||
|
|
"Pistol",
|
||
|
|
15f,
|
||
|
|
0.25f,
|
||
|
|
8,
|
||
|
|
40,
|
||
|
|
0.02f,
|
||
|
|
1.2f,
|
||
|
|
1.5f,
|
||
|
|
1,
|
||
|
|
80f,
|
||
|
|
false,
|
||
|
|
pistolMaterial.color,
|
||
|
|
"Accurate semi-automatic weapon for medium range.",
|
||
|
|
muzzleFlashPrefab,
|
||
|
|
hitEffectPrefab);
|
||
|
|
|
||
|
|
WeaponData rifleData = CreateWeaponData(
|
||
|
|
"RifleData",
|
||
|
|
"Rifle",
|
||
|
|
10f,
|
||
|
|
0.1f,
|
||
|
|
30,
|
||
|
|
90,
|
||
|
|
0.06f,
|
||
|
|
2f,
|
||
|
|
2f,
|
||
|
|
1,
|
||
|
|
100f,
|
||
|
|
true,
|
||
|
|
rifleMaterial.color,
|
||
|
|
"Automatic rifle with high fire rate and moderate spread.",
|
||
|
|
muzzleFlashPrefab,
|
||
|
|
hitEffectPrefab);
|
||
|
|
|
||
|
|
WeaponData shotgunData = CreateWeaponData(
|
||
|
|
"ShotgunData",
|
||
|
|
"Shotgun",
|
||
|
|
8f,
|
||
|
|
0.8f,
|
||
|
|
5,
|
||
|
|
25,
|
||
|
|
0.18f,
|
||
|
|
4f,
|
||
|
|
2.5f,
|
||
|
|
8,
|
||
|
|
45f,
|
||
|
|
false,
|
||
|
|
shotgunMaterial.color,
|
||
|
|
"Close-range shotgun that fires several pellets per shot.",
|
||
|
|
muzzleFlashPrefab,
|
||
|
|
hitEffectPrefab);
|
||
|
|
|
||
|
|
CreateWeaponData(
|
||
|
|
"SMGData",
|
||
|
|
"SMG",
|
||
|
|
7f,
|
||
|
|
0.075f,
|
||
|
|
24,
|
||
|
|
120,
|
||
|
|
0.08f,
|
||
|
|
1.6f,
|
||
|
|
1.8f,
|
||
|
|
1,
|
||
|
|
75f,
|
||
|
|
true,
|
||
|
|
smgMaterial.color,
|
||
|
|
"Additional data-only weapon example. It is not active in the scene.",
|
||
|
|
muzzleFlashPrefab,
|
||
|
|
hitEffectPrefab);
|
||
|
|
|
||
|
|
CreateWeaponPrefabTemplate("Pistol", pistolData, pistolMaterial);
|
||
|
|
CreateWeaponPrefabTemplate("Rifle", rifleData, rifleMaterial);
|
||
|
|
CreateWeaponPrefabTemplate("Shotgun", shotgunData, shotgunMaterial);
|
||
|
|
|
||
|
|
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||
|
|
Scene scene = SceneManager.GetActiveScene();
|
||
|
|
|
||
|
|
CreateLighting();
|
||
|
|
CreateEnvironment(floorMaterial, wallMaterial);
|
||
|
|
|
||
|
|
WeaponHUD hud = CreateUI(uiFont, out Text ammoText, out Text weaponNameText, out Text reloadText);
|
||
|
|
GameObject player = CreatePlayer(out Camera playerCamera, out Transform weaponHolder);
|
||
|
|
|
||
|
|
Weapon pistol = CreateSceneWeapon("Pistol", pistolData, pistolMaterial, weaponHolder, playerCamera, hud, ammoText, weaponNameText, reloadText, new Vector3(0f, 0f, 0f));
|
||
|
|
Weapon rifle = CreateSceneWeapon("Rifle", rifleData, rifleMaterial, weaponHolder, playerCamera, hud, ammoText, weaponNameText, reloadText, new Vector3(0f, -0.02f, 0.02f));
|
||
|
|
Weapon shotgun = CreateSceneWeapon("Shotgun", shotgunData, shotgunMaterial, weaponHolder, playerCamera, hud, ammoText, weaponNameText, reloadText, new Vector3(0f, -0.02f, 0.02f));
|
||
|
|
|
||
|
|
WeaponSwitcher switcher = player.AddComponent<WeaponSwitcher>();
|
||
|
|
switcher.weapons = new[] { pistol, rifle, shotgun };
|
||
|
|
switcher.currentIndex = 0;
|
||
|
|
switcher.weaponNameText = weaponNameText;
|
||
|
|
switcher.hud = hud;
|
||
|
|
|
||
|
|
pistol.gameObject.SetActive(true);
|
||
|
|
rifle.gameObject.SetActive(false);
|
||
|
|
shotgun.gameObject.SetActive(false);
|
||
|
|
|
||
|
|
CreateTargets(targetMaterial, uiFont);
|
||
|
|
|
||
|
|
EditorSceneManager.SaveScene(scene, ScenePath);
|
||
|
|
AssetDatabase.SaveAssets();
|
||
|
|
AssetDatabase.Refresh();
|
||
|
|
|
||
|
|
string resultMessage = "Weapon system scene was generated: " + ScenePath;
|
||
|
|
if (Application.isBatchMode)
|
||
|
|
Debug.Log(resultMessage);
|
||
|
|
else
|
||
|
|
EditorUtility.DisplayDialog("Lab 2", resultMessage, "OK");
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateFolders()
|
||
|
|
{
|
||
|
|
EnsureFolder(ScriptsFolder);
|
||
|
|
EnsureFolder(DataFolder);
|
||
|
|
EnsureFolder(PrefabsFolder);
|
||
|
|
EnsureFolder(ScenesFolder);
|
||
|
|
EnsureFolder(MaterialsFolder);
|
||
|
|
EnsureFolder(FontsFolder);
|
||
|
|
EnsureFolder(EditorFolder);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void EnsureFolder(string path)
|
||
|
|
{
|
||
|
|
if (AssetDatabase.IsValidFolder(path))
|
||
|
|
return;
|
||
|
|
|
||
|
|
string parent = System.IO.Path.GetDirectoryName(path)?.Replace("\\", "/");
|
||
|
|
string name = System.IO.Path.GetFileName(path);
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(parent))
|
||
|
|
parent = "Assets";
|
||
|
|
|
||
|
|
AssetDatabase.CreateFolder(parent, name);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Material CreateMaterial(string assetName, Color color)
|
||
|
|
{
|
||
|
|
string path = MaterialsFolder + "/" + assetName + ".mat";
|
||
|
|
Material material = AssetDatabase.LoadAssetAtPath<Material>(path);
|
||
|
|
|
||
|
|
if (material == null)
|
||
|
|
{
|
||
|
|
Shader shader = Shader.Find("Standard");
|
||
|
|
material = new Material(shader);
|
||
|
|
AssetDatabase.CreateAsset(material, path);
|
||
|
|
}
|
||
|
|
|
||
|
|
material.color = color;
|
||
|
|
EditorUtility.SetDirty(material);
|
||
|
|
return material;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Font CreateOrLoadUbuntuFont()
|
||
|
|
{
|
||
|
|
const string fontAssetPath = FontsFolder + "/Ubuntu-Regular.ttf";
|
||
|
|
|
||
|
|
Font projectFont = AssetDatabase.LoadAssetAtPath<Font>(fontAssetPath);
|
||
|
|
if (projectFont != null)
|
||
|
|
return projectFont;
|
||
|
|
|
||
|
|
string[] ubuntuFontCandidates =
|
||
|
|
{
|
||
|
|
"/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf",
|
||
|
|
"/usr/share/fonts/truetype/ubuntu/Ubuntu-Regular.ttf",
|
||
|
|
"/usr/share/fonts/TTF/Ubuntu-R.ttf",
|
||
|
|
"/home/ruby/.local/share/fonts/Ubuntu-R.ttf",
|
||
|
|
"/home/ruby/.local/share/fonts/Ubuntu-Regular.ttf"
|
||
|
|
};
|
||
|
|
|
||
|
|
foreach (string sourcePath in ubuntuFontCandidates)
|
||
|
|
{
|
||
|
|
if (!System.IO.File.Exists(sourcePath))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
FileUtil.CopyFileOrDirectory(sourcePath, fontAssetPath);
|
||
|
|
AssetDatabase.ImportAsset(fontAssetPath, ImportAssetOptions.ForceUpdate);
|
||
|
|
projectFont = AssetDatabase.LoadAssetAtPath<Font>(fontAssetPath);
|
||
|
|
|
||
|
|
if (projectFont != null)
|
||
|
|
return projectFont;
|
||
|
|
}
|
||
|
|
|
||
|
|
Font osUbuntuFont = Font.CreateDynamicFontFromOSFont("Ubuntu", 18);
|
||
|
|
if (osUbuntuFont != null)
|
||
|
|
return osUbuntuFont;
|
||
|
|
|
||
|
|
return Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||
|
|
}
|
||
|
|
|
||
|
|
private static GameObject CreateEffectPrefab(string name, Material material, Vector3 scale)
|
||
|
|
{
|
||
|
|
string path = PrefabsFolder + "/" + name + ".prefab";
|
||
|
|
GameObject temp = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||
|
|
temp.name = name;
|
||
|
|
temp.transform.localScale = scale;
|
||
|
|
|
||
|
|
Collider collider = temp.GetComponent<Collider>();
|
||
|
|
if (collider != null)
|
||
|
|
Object.DestroyImmediate(collider);
|
||
|
|
|
||
|
|
Renderer renderer = temp.GetComponent<Renderer>();
|
||
|
|
renderer.sharedMaterial = material;
|
||
|
|
|
||
|
|
GameObject prefab = PrefabUtility.SaveAsPrefabAsset(temp, path);
|
||
|
|
Object.DestroyImmediate(temp);
|
||
|
|
return prefab;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static WeaponData CreateWeaponData(
|
||
|
|
string assetName,
|
||
|
|
string weaponName,
|
||
|
|
float damage,
|
||
|
|
float fireRate,
|
||
|
|
int magazineSize,
|
||
|
|
int reserveAmmo,
|
||
|
|
float spread,
|
||
|
|
float recoilForce,
|
||
|
|
float reloadTime,
|
||
|
|
int pelletsPerShot,
|
||
|
|
float range,
|
||
|
|
bool automatic,
|
||
|
|
Color weaponColor,
|
||
|
|
string description,
|
||
|
|
GameObject muzzleFlashPrefab,
|
||
|
|
GameObject hitEffectPrefab)
|
||
|
|
{
|
||
|
|
string path = DataFolder + "/" + assetName + ".asset";
|
||
|
|
WeaponData data = AssetDatabase.LoadAssetAtPath<WeaponData>(path);
|
||
|
|
|
||
|
|
if (data == null)
|
||
|
|
{
|
||
|
|
data = ScriptableObject.CreateInstance<WeaponData>();
|
||
|
|
AssetDatabase.CreateAsset(data, path);
|
||
|
|
}
|
||
|
|
|
||
|
|
data.weaponName = weaponName;
|
||
|
|
data.damage = damage;
|
||
|
|
data.fireRate = fireRate;
|
||
|
|
data.magazineSize = magazineSize;
|
||
|
|
data.totalReserveAmmo = reserveAmmo;
|
||
|
|
data.spread = spread;
|
||
|
|
data.recoilForce = recoilForce;
|
||
|
|
data.reloadTime = reloadTime;
|
||
|
|
data.pelletsPerShot = pelletsPerShot;
|
||
|
|
data.range = range;
|
||
|
|
data.automatic = automatic;
|
||
|
|
data.weaponColor = weaponColor;
|
||
|
|
data.description = description;
|
||
|
|
data.muzzleFlashPrefab = muzzleFlashPrefab;
|
||
|
|
data.hitEffectPrefab = hitEffectPrefab;
|
||
|
|
|
||
|
|
EditorUtility.SetDirty(data);
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateWeaponPrefabTemplate(string name, WeaponData data, Material material)
|
||
|
|
{
|
||
|
|
GameObject root = BuildWeaponModel(name, data, material);
|
||
|
|
Weapon weapon = root.AddComponent<Weapon>();
|
||
|
|
weapon.data = data;
|
||
|
|
weapon.firePoint = root.transform.Find("FirePoint");
|
||
|
|
|
||
|
|
PrefabUtility.SaveAsPrefabAsset(root, PrefabsFolder + "/" + name + ".prefab");
|
||
|
|
Object.DestroyImmediate(root);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateLighting()
|
||
|
|
{
|
||
|
|
GameObject lightObject = new GameObject("Directional Light");
|
||
|
|
Light light = lightObject.AddComponent<Light>();
|
||
|
|
light.type = LightType.Directional;
|
||
|
|
light.intensity = 1.2f;
|
||
|
|
lightObject.transform.rotation = Quaternion.Euler(50f, -30f, 0f);
|
||
|
|
|
||
|
|
RenderSettings.ambientLight = new Color(0.45f, 0.45f, 0.45f);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateEnvironment(Material floorMaterial, Material wallMaterial)
|
||
|
|
{
|
||
|
|
GameObject floor = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||
|
|
floor.name = "Floor";
|
||
|
|
floor.transform.localScale = new Vector3(4f, 1f, 4f);
|
||
|
|
floor.GetComponent<Renderer>().sharedMaterial = floorMaterial;
|
||
|
|
|
||
|
|
CreateWall("Back Wall", new Vector3(0f, 2f, 18f), new Vector3(22f, 4f, 0.35f), wallMaterial);
|
||
|
|
CreateWall("Left Wall", new Vector3(-11f, 2f, 6f), new Vector3(0.35f, 4f, 24f), wallMaterial);
|
||
|
|
CreateWall("Right Wall", new Vector3(11f, 2f, 6f), new Vector3(0.35f, 4f, 24f), wallMaterial);
|
||
|
|
CreateWall("Low Cover", new Vector3(0f, 0.75f, 7f), new Vector3(4f, 1.5f, 0.4f), wallMaterial);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateWall(string name, Vector3 position, Vector3 scale, Material material)
|
||
|
|
{
|
||
|
|
GameObject wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
|
|
wall.name = name;
|
||
|
|
wall.transform.position = position;
|
||
|
|
wall.transform.localScale = scale;
|
||
|
|
wall.GetComponent<Renderer>().sharedMaterial = material;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static GameObject CreatePlayer(out Camera playerCamera, out Transform weaponHolder)
|
||
|
|
{
|
||
|
|
GameObject player = new GameObject("Player");
|
||
|
|
player.transform.position = new Vector3(0f, 1.1f, -6f);
|
||
|
|
|
||
|
|
CharacterController controller = player.AddComponent<CharacterController>();
|
||
|
|
controller.height = 1.8f;
|
||
|
|
controller.radius = 0.35f;
|
||
|
|
controller.center = new Vector3(0f, 0.9f, 0f);
|
||
|
|
|
||
|
|
SimpleFPSController fpsController = player.AddComponent<SimpleFPSController>();
|
||
|
|
|
||
|
|
GameObject cameraObject = new GameObject("Main Camera");
|
||
|
|
cameraObject.tag = "MainCamera";
|
||
|
|
cameraObject.transform.SetParent(player.transform);
|
||
|
|
cameraObject.transform.localPosition = new Vector3(0f, 1.6f, 0f);
|
||
|
|
cameraObject.transform.localRotation = Quaternion.identity;
|
||
|
|
|
||
|
|
playerCamera = cameraObject.AddComponent<Camera>();
|
||
|
|
playerCamera.nearClipPlane = 0.01f;
|
||
|
|
playerCamera.fieldOfView = 70f;
|
||
|
|
cameraObject.AddComponent<AudioListener>();
|
||
|
|
fpsController.playerCamera = playerCamera;
|
||
|
|
|
||
|
|
GameObject holder = new GameObject("WeaponHolder");
|
||
|
|
holder.transform.SetParent(cameraObject.transform);
|
||
|
|
holder.transform.localPosition = new Vector3(0.38f, -0.34f, 0.72f);
|
||
|
|
holder.transform.localRotation = Quaternion.Euler(0f, -2f, 0f);
|
||
|
|
weaponHolder = holder.transform;
|
||
|
|
|
||
|
|
return player;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static WeaponHUD CreateUI(Font uiFont, out Text ammoText, out Text weaponNameText, out Text reloadText)
|
||
|
|
{
|
||
|
|
GameObject canvasObject = new GameObject("HUD Canvas");
|
||
|
|
Canvas canvas = canvasObject.AddComponent<Canvas>();
|
||
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||
|
|
|
||
|
|
CanvasScaler scaler = canvasObject.AddComponent<CanvasScaler>();
|
||
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||
|
|
scaler.referenceResolution = new Vector2(1920f, 1080f);
|
||
|
|
scaler.matchWidthOrHeight = 0.5f;
|
||
|
|
|
||
|
|
canvasObject.AddComponent<GraphicRaycaster>();
|
||
|
|
WeaponHUD hud = canvasObject.AddComponent<WeaponHUD>();
|
||
|
|
|
||
|
|
hud.labTitleText = CreateText(canvasObject.transform, "Lab Title", "Лабораторная работа №2 — Data-Driven система оружия", 30, TextAnchor.UpperLeft, new Vector2(24f, -18f), new Vector2(760f, 48f), new Vector2(0f, 1f), new Vector2(0f, 1f), uiFont);
|
||
|
|
weaponNameText = CreateText(canvasObject.transform, "Weapon Name", "Weapon: Pistol", 26, TextAnchor.UpperLeft, new Vector2(24f, -78f), new Vector2(360f, 38f), new Vector2(0f, 1f), new Vector2(0f, 1f), uiFont);
|
||
|
|
ammoText = CreateText(canvasObject.transform, "Ammo", "Ammo: 8 / 40", 26, TextAnchor.UpperLeft, new Vector2(24f, -118f), new Vector2(320f, 38f), new Vector2(0f, 1f), new Vector2(0f, 1f), uiFont);
|
||
|
|
reloadText = CreateText(canvasObject.transform, "Reload Status", "Ready", 24, TextAnchor.UpperLeft, new Vector2(24f, -158f), new Vector2(320f, 34f), new Vector2(0f, 1f), new Vector2(0f, 1f), uiFont);
|
||
|
|
|
||
|
|
hud.hintsText = CreateText(canvasObject.transform, "Controls Hint", "ЛКМ — стрелять\nR — перезарядка\n1/2/3 или колесо мыши — смена оружия\nWASD + мышь — движение", 21, TextAnchor.UpperLeft, new Vector2(24f, 152f), new Vector2(520f, 150f), new Vector2(0f, 0f), new Vector2(0f, 0f), uiFont);
|
||
|
|
hud.statsText = CreateText(canvasObject.transform, "Weapon Stats", string.Empty, 22, TextAnchor.UpperRight, new Vector2(-24f, -78f), new Vector2(330f, 190f), new Vector2(1f, 1f), new Vector2(1f, 1f), uiFont);
|
||
|
|
hud.messageText = CreateText(canvasObject.transform, "Message", string.Empty, 24, TextAnchor.MiddleCenter, new Vector2(0f, -210f), new Vector2(560f, 44f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), uiFont);
|
||
|
|
hud.dataDrivenText = CreateText(canvasObject.transform, "Data Driven Note", "Параметры оружия хранятся в ScriptableObject-ассетах в папке Assets/_Data. Для добавления нового оружия достаточно создать новый WeaponData и назначить его объекту Weapon.", 19, TextAnchor.LowerRight, new Vector2(-24f, 22f), new Vector2(720f, 82f), new Vector2(1f, 0f), new Vector2(1f, 0f), uiFont);
|
||
|
|
|
||
|
|
hud.weaponNameText = weaponNameText;
|
||
|
|
hud.ammoText = ammoText;
|
||
|
|
hud.reloadText = reloadText;
|
||
|
|
hud.SetReloading(false);
|
||
|
|
|
||
|
|
return hud;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Text CreateText(Transform parent, string name, string value, int fontSize, TextAnchor alignment, Vector2 anchoredPosition, Vector2 size, Vector2 anchorMin, Vector2 anchorMax, Font uiFont)
|
||
|
|
{
|
||
|
|
GameObject textObject = new GameObject(name);
|
||
|
|
textObject.transform.SetParent(parent, false);
|
||
|
|
|
||
|
|
RectTransform rect = textObject.AddComponent<RectTransform>();
|
||
|
|
rect.anchorMin = anchorMin;
|
||
|
|
rect.anchorMax = anchorMax;
|
||
|
|
rect.pivot = new Vector2(anchorMin.x == anchorMax.x ? anchorMin.x : 0.5f, anchorMin.y == anchorMax.y ? anchorMin.y : 0.5f);
|
||
|
|
rect.anchoredPosition = anchoredPosition;
|
||
|
|
rect.sizeDelta = size;
|
||
|
|
|
||
|
|
Text text = textObject.AddComponent<Text>();
|
||
|
|
text.text = value;
|
||
|
|
text.font = uiFont;
|
||
|
|
text.fontSize = fontSize;
|
||
|
|
text.alignment = alignment;
|
||
|
|
text.color = Color.white;
|
||
|
|
text.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||
|
|
text.verticalOverflow = VerticalWrapMode.Overflow;
|
||
|
|
|
||
|
|
Outline outline = textObject.AddComponent<Outline>();
|
||
|
|
outline.effectColor = new Color(0f, 0f, 0f, 0.85f);
|
||
|
|
outline.effectDistance = new Vector2(1.5f, -1.5f);
|
||
|
|
|
||
|
|
return text;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Weapon CreateSceneWeapon(
|
||
|
|
string name,
|
||
|
|
WeaponData data,
|
||
|
|
Material material,
|
||
|
|
Transform parent,
|
||
|
|
Camera playerCamera,
|
||
|
|
WeaponHUD hud,
|
||
|
|
Text ammoText,
|
||
|
|
Text weaponNameText,
|
||
|
|
Text reloadText,
|
||
|
|
Vector3 localOffset)
|
||
|
|
{
|
||
|
|
GameObject weaponObject = BuildWeaponModel(name, data, material);
|
||
|
|
weaponObject.transform.SetParent(parent, false);
|
||
|
|
weaponObject.transform.localPosition = localOffset;
|
||
|
|
weaponObject.transform.localRotation = Quaternion.identity;
|
||
|
|
|
||
|
|
Weapon weapon = weaponObject.AddComponent<Weapon>();
|
||
|
|
weapon.data = data;
|
||
|
|
weapon.playerCamera = playerCamera;
|
||
|
|
weapon.hud = hud;
|
||
|
|
weapon.ammoText = ammoText;
|
||
|
|
weapon.weaponNameText = weaponNameText;
|
||
|
|
weapon.reloadText = reloadText;
|
||
|
|
weapon.firePoint = weaponObject.transform.Find("FirePoint");
|
||
|
|
weaponObject.AddComponent<AudioSource>().spatialBlend = 0f;
|
||
|
|
|
||
|
|
return weapon;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static GameObject BuildWeaponModel(string name, WeaponData data, Material material)
|
||
|
|
{
|
||
|
|
GameObject root = new GameObject(name);
|
||
|
|
|
||
|
|
if (name == "Pistol")
|
||
|
|
{
|
||
|
|
AddPart(root.transform, "Slide", new Vector3(0f, 0f, 0.18f), new Vector3(0.18f, 0.12f, 0.55f), material);
|
||
|
|
AddPart(root.transform, "Grip", new Vector3(0f, -0.16f, -0.02f), new Vector3(0.14f, 0.34f, 0.16f), material);
|
||
|
|
AddPart(root.transform, "Barrel", new Vector3(0f, 0.02f, 0.52f), new Vector3(0.08f, 0.08f, 0.24f), material);
|
||
|
|
CreateFirePoint(root.transform, new Vector3(0f, 0.02f, 0.66f));
|
||
|
|
}
|
||
|
|
else if (name == "Rifle")
|
||
|
|
{
|
||
|
|
AddPart(root.transform, "Body", new Vector3(0f, 0f, 0.3f), new Vector3(0.18f, 0.14f, 0.95f), material);
|
||
|
|
AddPart(root.transform, "Stock", new Vector3(0f, 0f, -0.28f), new Vector3(0.2f, 0.16f, 0.34f), material);
|
||
|
|
AddPart(root.transform, "Grip", new Vector3(0f, -0.18f, 0.05f), new Vector3(0.12f, 0.34f, 0.14f), material);
|
||
|
|
AddPart(root.transform, "Barrel", new Vector3(0f, 0.02f, 0.92f), new Vector3(0.07f, 0.07f, 0.45f), material);
|
||
|
|
CreateFirePoint(root.transform, new Vector3(0f, 0.02f, 1.16f));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
AddPart(root.transform, "Wide Body", new Vector3(0f, 0f, 0.25f), new Vector3(0.24f, 0.16f, 0.86f), material);
|
||
|
|
AddPart(root.transform, "Pump", new Vector3(0f, -0.08f, 0.54f), new Vector3(0.28f, 0.12f, 0.28f), material);
|
||
|
|
AddPart(root.transform, "Grip", new Vector3(0f, -0.20f, -0.04f), new Vector3(0.13f, 0.36f, 0.16f), material);
|
||
|
|
AddPart(root.transform, "Short Barrel", new Vector3(0f, 0.04f, 0.88f), new Vector3(0.14f, 0.10f, 0.36f), material);
|
||
|
|
CreateFirePoint(root.transform, new Vector3(0f, 0.04f, 1.08f));
|
||
|
|
}
|
||
|
|
|
||
|
|
root.transform.localRotation = Quaternion.identity;
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void AddPart(Transform parent, string name, Vector3 localPosition, Vector3 localScale, Material material)
|
||
|
|
{
|
||
|
|
GameObject part = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
|
|
part.name = name;
|
||
|
|
part.transform.SetParent(parent, false);
|
||
|
|
part.transform.localPosition = localPosition;
|
||
|
|
part.transform.localScale = localScale;
|
||
|
|
|
||
|
|
Collider collider = part.GetComponent<Collider>();
|
||
|
|
if (collider != null)
|
||
|
|
Object.DestroyImmediate(collider);
|
||
|
|
|
||
|
|
part.GetComponent<Renderer>().sharedMaterial = material;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateFirePoint(Transform parent, Vector3 localPosition)
|
||
|
|
{
|
||
|
|
GameObject firePoint = new GameObject("FirePoint");
|
||
|
|
firePoint.transform.SetParent(parent, false);
|
||
|
|
firePoint.transform.localPosition = localPosition;
|
||
|
|
firePoint.transform.localRotation = Quaternion.identity;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateTargets(Material targetMaterial, Font uiFont)
|
||
|
|
{
|
||
|
|
List<Vector3> positions = new List<Vector3>
|
||
|
|
{
|
||
|
|
new Vector3(-3.5f, 1f, 5f),
|
||
|
|
new Vector3(0f, 1f, 8f),
|
||
|
|
new Vector3(3.5f, 1f, 11f),
|
||
|
|
new Vector3(-5.5f, 1f, 14f),
|
||
|
|
new Vector3(5.5f, 1f, 16f)
|
||
|
|
};
|
||
|
|
|
||
|
|
for (int i = 0; i < positions.Count; i++)
|
||
|
|
CreateTarget("EnemyTarget_" + (i + 1), positions[i], targetMaterial, uiFont);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void CreateTarget(string name, Vector3 position, Material material, Font uiFont)
|
||
|
|
{
|
||
|
|
GameObject target = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
|
|
target.name = name;
|
||
|
|
target.transform.position = position;
|
||
|
|
target.transform.localScale = new Vector3(1.2f, 2f, 0.35f);
|
||
|
|
target.GetComponent<Renderer>().sharedMaterial = material;
|
||
|
|
|
||
|
|
EnemyTarget enemyTarget = target.AddComponent<EnemyTarget>();
|
||
|
|
enemyTarget.maxHealth = 100f;
|
||
|
|
enemyTarget.targetRenderer = target.GetComponent<Renderer>();
|
||
|
|
|
||
|
|
GameObject canvasObject = new GameObject("Health Canvas");
|
||
|
|
canvasObject.transform.SetParent(target.transform, false);
|
||
|
|
canvasObject.transform.localPosition = new Vector3(0f, 1.25f, 0f);
|
||
|
|
canvasObject.transform.localScale = Vector3.one * 0.012f;
|
||
|
|
|
||
|
|
Canvas canvas = canvasObject.AddComponent<Canvas>();
|
||
|
|
canvas.renderMode = RenderMode.WorldSpace;
|
||
|
|
|
||
|
|
RectTransform canvasRect = canvasObject.GetComponent<RectTransform>();
|
||
|
|
canvasRect.sizeDelta = new Vector2(220f, 50f);
|
||
|
|
|
||
|
|
Text healthText = CreateText(canvasObject.transform, "Health Text", "HP: 100 / 100", 24, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(220f, 50f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), uiFont);
|
||
|
|
enemyTarget.healthText = healthText;
|
||
|
|
}
|
||
|
|
}
|