234 lines
11 KiB
C#
234 lines
11 KiB
C#
using UnityEngine;
|
||
using UnityEditor;
|
||
using UnityEngine.UI;
|
||
|
||
public static class SetupShootingAndAmmo
|
||
{
|
||
[MenuItem("Tools/Setup Shooting & Ammo System")]
|
||
public static void Setup()
|
||
{
|
||
// 1. Находим игрока (PlayerMovement)
|
||
PlayerMovement playerMovement = Object.FindAnyObjectByType<PlayerMovement>();
|
||
if (playerMovement == null)
|
||
{
|
||
Debug.LogError("[Setup] Не найден объект игрока с компонентом PlayerMovement!");
|
||
return;
|
||
}
|
||
|
||
GameObject playerGo = playerMovement.gameObject;
|
||
Undo.RegisterFullObjectHierarchyUndo(playerGo, "Setup Shooting");
|
||
|
||
// 2. Добавляем / настраиваем PlayerGun на игроке
|
||
PlayerGun playerGun = playerGo.GetComponent<PlayerGun>();
|
||
if (playerGun == null)
|
||
{
|
||
playerGun = playerGo.AddComponent<PlayerGun>();
|
||
}
|
||
|
||
// 3. Создаем плейсхолдер модель оружия (GunHolder), если еще нет
|
||
Transform existingGun = playerGo.transform.Find("GunHolder");
|
||
if (existingGun != null)
|
||
{
|
||
Object.DestroyImmediate(existingGun.gameObject);
|
||
}
|
||
|
||
GameObject gunHolder = new GameObject("GunHolder");
|
||
gunHolder.transform.SetParent(playerGo.transform, false);
|
||
// Позиционируем справа на уровне пояса / руки
|
||
gunHolder.transform.localPosition = new Vector3(0.35f, 1.0f, 0.45f);
|
||
gunHolder.transform.localRotation = Quaternion.identity;
|
||
|
||
// Создаем детали пистолета-заглушки
|
||
// А. Затвор / Ствол
|
||
GameObject slide = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
slide.name = "Pistol_Slide";
|
||
slide.transform.SetParent(gunHolder.transform, false);
|
||
slide.transform.localPosition = new Vector3(0f, 0.05f, 0.1f);
|
||
slide.transform.localScale = new Vector3(0.08f, 0.08f, 0.3f);
|
||
Object.DestroyImmediate(slide.GetComponent<Collider>());
|
||
|
||
// Б. Рукоятка
|
||
GameObject grip = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
grip.name = "Pistol_Grip";
|
||
grip.transform.SetParent(gunHolder.transform, false);
|
||
grip.transform.localPosition = new Vector3(0f, -0.05f, 0.02f);
|
||
grip.transform.localRotation = Quaternion.Euler(15f, 0f, 0f);
|
||
grip.transform.localScale = new Vector3(0.07f, 0.16f, 0.08f);
|
||
Object.DestroyImmediate(grip.GetComponent<Collider>());
|
||
|
||
// В. Ствол на конце
|
||
GameObject barrel = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||
barrel.name = "Pistol_Barrel";
|
||
barrel.transform.SetParent(gunHolder.transform, false);
|
||
barrel.transform.localPosition = new Vector3(0f, 0.05f, 0.26f);
|
||
barrel.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
|
||
barrel.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f);
|
||
Object.DestroyImmediate(barrel.GetComponent<Collider>());
|
||
|
||
// Точка вылета пули
|
||
GameObject muzzleGo = new GameObject("MuzzlePoint");
|
||
muzzleGo.transform.SetParent(gunHolder.transform, false);
|
||
muzzleGo.transform.localPosition = new Vector3(0f, 0.05f, 0.32f);
|
||
|
||
// Вспышка (свет)
|
||
GameObject flashGo = new GameObject("MuzzleFlashLight");
|
||
flashGo.transform.SetParent(muzzleGo.transform, false);
|
||
flashGo.transform.localPosition = Vector3.zero;
|
||
Light flashLight = flashGo.AddComponent<Light>();
|
||
flashLight.type = LightType.Point;
|
||
flashLight.color = new Color(1f, 0.85f, 0.4f);
|
||
flashLight.range = 5f;
|
||
flashLight.intensity = 3f;
|
||
flashLight.enabled = false;
|
||
|
||
// Назначаем ссылки в PlayerGun
|
||
playerGun.gunModelTransform = gunHolder.transform;
|
||
playerGun.muzzlePoint = muzzleGo.transform;
|
||
playerGun.muzzleFlashLight = flashLight;
|
||
playerGun.isGunEquipped = false;
|
||
playerGun.UpdateGunVisibility();
|
||
|
||
// Покрасим пистолет в стильный темный цвет
|
||
Material gunMat = new Material(Shader.Find("Universal Render Pipeline/Lit"));
|
||
if (gunMat.shader == null || !gunMat.shader.isSupported)
|
||
{
|
||
gunMat = new Material(Shader.Find("Standard"));
|
||
}
|
||
gunMat.color = new Color(0.15f, 0.16f, 0.18f, 1f);
|
||
slide.GetComponent<Renderer>().material = gunMat;
|
||
grip.GetComponent<Renderer>().material = gunMat;
|
||
barrel.GetComponent<Renderer>().material = gunMat;
|
||
|
||
// 4. Настраиваем UI патронов на HUD_Canvas
|
||
GameObject canvasGo = GameObject.Find("HUD_Canvas");
|
||
if (canvasGo == null)
|
||
{
|
||
SetupHealthBarHUD.Setup();
|
||
canvasGo = GameObject.Find("HUD_Canvas");
|
||
}
|
||
|
||
Transform existingAmmoUI = canvasGo.transform.Find("AmmoPanel");
|
||
if (existingAmmoUI != null)
|
||
{
|
||
Object.DestroyImmediate(existingAmmoUI.gameObject);
|
||
}
|
||
|
||
// Ammo Root Container (под полоской здоровья)
|
||
GameObject ammoContainer = new GameObject("AmmoPanel", typeof(RectTransform));
|
||
ammoContainer.transform.SetParent(canvasGo.transform, false);
|
||
RectTransform ammoRect = ammoContainer.GetComponent<RectTransform>();
|
||
ammoRect.anchorMin = new Vector2(1f, 1f);
|
||
ammoRect.anchorMax = new Vector2(1f, 1f);
|
||
ammoRect.pivot = new Vector2(1f, 1f);
|
||
ammoRect.anchoredPosition = new Vector2(-40f, -84f);
|
||
ammoRect.sizeDelta = new Vector2(280f, 40f);
|
||
|
||
// Background
|
||
GameObject bgGo = new GameObject("Background", typeof(RectTransform), typeof(Image));
|
||
bgGo.transform.SetParent(ammoContainer.transform, false);
|
||
RectTransform bgRect = bgGo.GetComponent<RectTransform>();
|
||
bgRect.anchorMin = Vector2.zero;
|
||
bgRect.anchorMax = Vector2.one;
|
||
bgRect.offsetMin = Vector2.zero;
|
||
bgRect.offsetMax = Vector2.zero;
|
||
Image bgImg = bgGo.GetComponent<Image>();
|
||
bgImg.color = new Color(0.08f, 0.08f, 0.08f, 0.85f);
|
||
|
||
Font defaultFont = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||
if (defaultFont == null) defaultFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||
|
||
// Иконка / Лейбл "AMMO"
|
||
GameObject labelGo = new GameObject("Text_Label", typeof(RectTransform), typeof(Text));
|
||
labelGo.transform.SetParent(ammoContainer.transform, false);
|
||
RectTransform labelRect = labelGo.GetComponent<RectTransform>();
|
||
labelRect.anchorMin = new Vector2(0f, 0f);
|
||
labelRect.anchorMax = new Vector2(0.4f, 1f);
|
||
labelRect.offsetMin = new Vector2(12f, 0f);
|
||
labelRect.offsetMax = Vector2.zero;
|
||
Text labelText = labelGo.GetComponent<Text>();
|
||
labelText.text = "ПАТРОНЫ";
|
||
labelText.font = defaultFont;
|
||
labelText.fontSize = 14;
|
||
labelText.fontStyle = FontStyle.Bold;
|
||
labelText.alignment = TextAnchor.MiddleLeft;
|
||
labelText.color = new Color(0.7f, 0.7f, 0.7f, 0.9f);
|
||
|
||
// Текст патронов (7 / 21)
|
||
GameObject countGo = new GameObject("Text_Count", typeof(RectTransform), typeof(Text));
|
||
countGo.transform.SetParent(ammoContainer.transform, false);
|
||
RectTransform countRect = countGo.GetComponent<RectTransform>();
|
||
countRect.anchorMin = new Vector2(0.4f, 0f);
|
||
countRect.anchorMax = new Vector2(1f, 1f);
|
||
countRect.offsetMin = Vector2.zero;
|
||
countRect.offsetMax = new Vector2(-12f, 0f);
|
||
Text countText = countGo.GetComponent<Text>();
|
||
countText.text = "7 / 21";
|
||
countText.font = defaultFont;
|
||
countText.fontSize = 20;
|
||
countText.fontStyle = FontStyle.Bold;
|
||
countText.alignment = TextAnchor.MiddleRight;
|
||
countText.color = Color.white;
|
||
|
||
// Текст статуса / подсказки под панелью
|
||
GameObject statusGo = new GameObject("Text_Status", typeof(RectTransform), typeof(Text));
|
||
statusGo.transform.SetParent(ammoContainer.transform, false);
|
||
RectTransform statusRect = statusGo.GetComponent<RectTransform>();
|
||
statusRect.anchorMin = new Vector2(0f, 0f);
|
||
statusRect.anchorMax = new Vector2(1f, 0f);
|
||
statusRect.pivot = new Vector2(0.5f, 1f);
|
||
statusRect.anchoredPosition = new Vector2(0f, -4f);
|
||
statusRect.sizeDelta = new Vector2(280f, 22f);
|
||
Text statusText = statusGo.GetComponent<Text>();
|
||
statusText.text = "";
|
||
statusText.font = defaultFont;
|
||
statusText.fontSize = 13;
|
||
statusText.fontStyle = FontStyle.Bold;
|
||
statusText.alignment = TextAnchor.MiddleRight;
|
||
statusText.color = new Color(1f, 0.85f, 0.2f, 1f);
|
||
|
||
// PlayerAmmoUI компонент
|
||
PlayerAmmoUI ammoUI = ammoContainer.AddComponent<PlayerAmmoUI>();
|
||
ammoUI.playerGun = playerGun;
|
||
ammoUI.ammoText = countText;
|
||
ammoUI.statusText = statusText;
|
||
|
||
// 5. Создаем 2 коробки с патронами на уровне рядом с игроком
|
||
CreateAmmoBox(playerGo.transform.position + playerGo.transform.forward * 3f + playerGo.transform.right * 1.5f, 14);
|
||
CreateAmmoBox(playerGo.transform.position + playerGo.transform.forward * 6f - playerGo.transform.right * 2f, 21);
|
||
|
||
Undo.RegisterCreatedObjectUndo(gunHolder, "Create Gun Holder");
|
||
Undo.RegisterCreatedObjectUndo(ammoContainer, "Create Ammo HUD");
|
||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(playerGo.scene);
|
||
|
||
Debug.Log("<color=green>[Setup] Механика стрельбы, пистолет, патроны и UI успешно настроены!</color>");
|
||
}
|
||
|
||
private static void CreateAmmoBox(Vector3 position, int ammoCount)
|
||
{
|
||
GameObject boxGo = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
boxGo.name = $"AmmoBox_({ammoCount})";
|
||
boxGo.transform.position = position + Vector3.up * 0.25f;
|
||
boxGo.transform.localScale = new Vector3(0.4f, 0.3f, 0.3f);
|
||
|
||
// Коллайдер делаем триггером
|
||
Collider col = boxGo.GetComponent<Collider>();
|
||
col.isTrigger = true;
|
||
|
||
// Скрипт подбора
|
||
AmmoPickup pickup = boxGo.AddComponent<AmmoPickup>();
|
||
pickup.ammoAmount = ammoCount;
|
||
pickup.pickupOnTouch = true;
|
||
|
||
// Военный зеленый / оранжевый материал
|
||
Material boxMat = new Material(Shader.Find("Universal Render Pipeline/Lit"));
|
||
if (boxMat.shader == null || !boxMat.shader.isSupported)
|
||
{
|
||
boxMat = new Material(Shader.Find("Standard"));
|
||
}
|
||
boxMat.color = new Color(0.2f, 0.45f, 0.25f, 1f); // Темно-зеленый армейский ящик
|
||
boxGo.GetComponent<Renderer>().material = boxMat;
|
||
|
||
Undo.RegisterCreatedObjectUndo(boxGo, "Create Ammo Box");
|
||
}
|
||
}
|