Kursach_StealthAction/Assets/Scripts/Editor/DeathScreenBuilder.cs

235 lines
9.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using UnityEditor.SceneManagement;
public static class DeathScreenBuilder
{
private static Font standardFont;
private static DefaultControls.Resources uiResources;
[MenuItem("Tools/Build Death Screen In Scene")]
public static string Build()
{
standardFont = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
if (standardFont == null)
standardFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
uiResources = new DefaultControls.Resources();
// 1. Находим PauseCanvas или Canvas в сцене
GameObject canvasGo = GameObject.Find("PauseCanvas");
if (canvasGo == null)
{
canvasGo = GameObject.Find("Canvas");
}
if (canvasGo == null)
{
// Создаем новый Canvas
canvasGo = new GameObject("DeathCanvas");
Canvas canvas = canvasGo.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 100;
CanvasScaler scaler = canvasGo.AddComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1920, 1080);
scaler.matchWidthOrHeight = 0.5f;
canvasGo.AddComponent<GraphicRaycaster>();
}
Undo.RegisterFullObjectHierarchyUndo(canvasGo, "Build Death Screen");
// Удаляем старый DeathScreenPanel, если был
Transform oldPanel = canvasGo.transform.Find("DeathScreenPanel");
if (oldPanel != null)
{
Undo.DestroyObjectImmediate(oldPanel.gameObject);
}
// 2. Создаем фоновую панель затемнения (DeathScreenPanel)
GameObject deathPanel = CreateImage("DeathScreenPanel", canvasGo.transform,
new Color(0.05f, 0.01f, 0.015f, 0.92f), // Глубокий темно-бордовый фон
Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
CanvasGroup cg = deathPanel.AddComponent<CanvasGroup>();
cg.alpha = 1f;
// 3. Центральная карточка (Death_Card)
GameObject card = CreateImage("Death_Card", deathPanel.transform,
new Color(0.10f, 0.03f, 0.045f, 0.98f),
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f),
new Vector2(520f, 440f), Vector2.zero);
// Кроваво-красная светящаяся рамка
Outline outline = card.AddComponent<Outline>();
outline.effectColor = new Color(0.95f, 0.15f, 0.20f, 0.70f);
outline.effectDistance = new Vector2(2f, -2f);
Shadow shadow = card.AddComponent<Shadow>();
shadow.effectColor = new Color(0.5f, 0.0f, 0.05f, 0.5f);
shadow.effectDistance = new Vector2(6f, -6f);
// 4. Заголовок "ВЫ ПОГИБЛИ"
CreateText("Death_Title", card.transform,
"ВЫ ПОГИБЛИ",
40, FontStyle.Bold, TextAnchor.MiddleCenter,
new Color(1f, 0.22f, 0.22f, 1f),
new Vector2(0.05f, 0.76f), new Vector2(0.95f, 0.95f), Vector2.zero, Vector2.zero);
// Разделительная линия
CreateImage("Death_Divider", card.transform,
new Color(0.95f, 0.20f, 0.25f, 0.55f),
new Vector2(0.12f, 0.74f), new Vector2(0.88f, 0.745f), Vector2.zero, Vector2.zero);
// Подзаголовок
CreateText("Death_Subtitle", card.transform,
"Биометрические показатели на нуле.\nСвязь с комплексом потеряна.",
16, FontStyle.Normal, TextAnchor.MiddleCenter,
new Color(0.90f, 0.78f, 0.80f, 0.90f),
new Vector2(0.08f, 0.58f), new Vector2(0.92f, 0.72f), Vector2.zero, Vector2.zero);
// 5. Контейнер кнопок
GameObject btnContainer = CreateEmptyRect("Buttons_Container", card.transform,
new Vector2(0.10f, 0.08f), new Vector2(0.90f, 0.54f), Vector2.zero, Vector2.zero);
VerticalLayoutGroup vLayout = btnContainer.AddComponent<VerticalLayoutGroup>();
vLayout.spacing = 16f;
vLayout.childAlignment = TextAnchor.MiddleCenter;
vLayout.childControlWidth = true;
vLayout.childControlHeight = false;
vLayout.childForceExpandWidth = true;
vLayout.childForceExpandHeight = false;
// Кнопка "Начать заново"
Button restartBtn = CreateStyledButton("Btn_Restart", btnContainer.transform,
"↺ НАЧАТЬ ЗАНОВО",
new Color(0.38f, 0.08f, 0.10f, 0.95f),
new Color(0.85f, 0.16f, 0.20f, 1.0f),
new Color(0.22f, 0.04f, 0.05f, 1.0f),
Color.white, 54f, 20);
// Кнопка "Главное меню"
Button mainMenuBtn = CreateStyledButton("Btn_MainMenu", btnContainer.transform,
"⮌ ГЛАВНОЕ МЕНЮ",
new Color(0.18f, 0.18f, 0.22f, 0.95f),
new Color(0.36f, 0.36f, 0.42f, 1.0f),
new Color(0.10f, 0.10f, 0.12f, 1.0f),
new Color(0.9f, 0.9f, 0.9f, 1f), 50f, 18);
// 6. Настраиваем компонент DeathScreenUI
DeathScreenUI deathUI = canvasGo.GetComponent<DeathScreenUI>();
if (deathUI == null)
deathUI = canvasGo.AddComponent<DeathScreenUI>();
deathUI.deathPanel = deathPanel;
deathUI.canvasGroup = cg;
deathUI.restartButton = restartBtn;
deathUI.mainMenuButton = mainMenuBtn;
deathUI.fadeDuration = 0.8f;
deathUI.mainMenuSceneName = "MainMenu";
UnityEditor.Events.UnityEventTools.AddPersistentListener(restartBtn.onClick, deathUI.RestartGame);
UnityEditor.Events.UnityEventTools.AddPersistentListener(mainMenuBtn.onClick, deathUI.ReturnToMainMenu);
// По умолчанию скрываем панель смерти
deathPanel.SetActive(false);
// 7. Привязываем к игроку (PlayerHealth)
GameObject player = GameObject.Find("Player");
if (player == null) player = GameObject.Find("Capsule");
if (player != null)
{
var ph = player.GetComponent<PlayerHealth>();
if (ph != null)
{
ph.deathScreenUI = deathUI;
EditorUtility.SetDirty(ph);
}
}
EditorUtility.SetDirty(deathUI);
EditorUtility.SetDirty(canvasGo);
EditorSceneManager.MarkSceneDirty(canvasGo.scene);
EditorSceneManager.SaveScene(canvasGo.scene);
Debug.Log("<color=green>[DeathScreenBuilder] Экран смерти успешно собран и настроен в сцене!</color>");
return "SUCCESS: Death screen successfully built and configured in scene!";
}
private static GameObject CreateImage(string name, Transform parent, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition)
{
GameObject go = CreateEmptyRect(name, parent, anchorMin, anchorMax, sizeDelta, anchoredPosition);
Image img = go.AddComponent<Image>();
img.color = color;
return go;
}
private static GameObject CreateEmptyRect(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition)
{
GameObject go = new GameObject(name);
go.transform.SetParent(parent, false);
RectTransform rt = go.AddComponent<RectTransform>();
rt.anchorMin = anchorMin;
rt.anchorMax = anchorMax;
rt.sizeDelta = sizeDelta;
rt.anchoredPosition = anchoredPosition;
return go;
}
private static GameObject CreateText(string name, Transform parent, string text, int fontSize, FontStyle style, TextAnchor alignment, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition)
{
GameObject go = CreateEmptyRect(name, parent, anchorMin, anchorMax, sizeDelta, anchoredPosition);
Text t = go.AddComponent<Text>();
t.font = standardFont;
t.text = text;
t.fontSize = fontSize;
t.fontStyle = style;
t.alignment = alignment;
t.color = color;
t.horizontalOverflow = HorizontalWrapMode.Wrap;
t.verticalOverflow = VerticalWrapMode.Overflow;
return go;
}
private static Button CreateStyledButton(string name, Transform parent, string label, Color normalColor, Color highlightedColor, Color pressedColor, Color textColor, float height, int fontSize)
{
GameObject btnObj = DefaultControls.CreateButton(uiResources);
btnObj.name = name;
btnObj.transform.SetParent(parent, false);
LayoutElement layout = btnObj.AddComponent<LayoutElement>();
layout.minHeight = height;
layout.preferredHeight = height;
Image img = btnObj.GetComponent<Image>();
img.color = normalColor;
img.type = Image.Type.Sliced;
Button btn = btnObj.GetComponent<Button>();
ColorBlock colors = btn.colors;
colors.normalColor = normalColor;
colors.highlightedColor = highlightedColor;
colors.pressedColor = pressedColor;
colors.selectedColor = highlightedColor;
colors.colorMultiplier = 1f;
colors.fadeDuration = 0.12f;
btn.colors = colors;
Text text = btnObj.GetComponentInChildren<Text>();
if (text != null)
{
text.font = standardFont;
text.text = label;
text.fontSize = fontSize;
text.fontStyle = FontStyle.Bold;
text.color = textColor;
text.alignment = TextAnchor.MiddleCenter;
}
return btn;
}
}