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(); if (playerMovement == null) { Debug.LogError("[Setup] Не найден объект игрока с компонентом PlayerMovement!"); return; } GameObject playerGo = playerMovement.gameObject; Undo.RegisterFullObjectHierarchyUndo(playerGo, "Setup Shooting"); // 2. Добавляем / настраиваем PlayerGun на игроке PlayerGun playerGun = playerGo.GetComponent(); if (playerGun == null) { playerGun = playerGo.AddComponent(); } // 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()); // Б. Рукоятка 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()); // В. Ствол на конце 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()); // Точка вылета пули 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(); 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().material = gunMat; grip.GetComponent().material = gunMat; barrel.GetComponent().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(); 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(); bgRect.anchorMin = Vector2.zero; bgRect.anchorMax = Vector2.one; bgRect.offsetMin = Vector2.zero; bgRect.offsetMax = Vector2.zero; Image bgImg = bgGo.GetComponent(); bgImg.color = new Color(0.08f, 0.08f, 0.08f, 0.85f); Font defaultFont = Resources.GetBuiltinResource("LegacyRuntime.ttf"); if (defaultFont == null) defaultFont = Resources.GetBuiltinResource("Arial.ttf"); // Иконка / Лейбл "AMMO" GameObject labelGo = new GameObject("Text_Label", typeof(RectTransform), typeof(Text)); labelGo.transform.SetParent(ammoContainer.transform, false); RectTransform labelRect = labelGo.GetComponent(); 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(); 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(); 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(); 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(); 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(); 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(); 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("[Setup] Механика стрельбы, пистолет, патроны и UI успешно настроены!"); } 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(); col.isTrigger = true; // Скрипт подбора AmmoPickup pickup = boxGo.AddComponent(); 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().material = boxMat; Undo.RegisterCreatedObjectUndo(boxGo, "Create Ammo Box"); } }