232 lines
9.5 KiB
C#
232 lines
9.5 KiB
C#
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";
|
||
|
||
// По умолчанию скрываем панель смерти
|
||
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;
|
||
}
|
||
}
|