using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.UI;
using UnityEngine.UI;
namespace Vanguard.UI
{
///
/// Минимальная фабрика uGUI. Экраны собираются кодом, чтобы каркас
/// запускался без префабов и ручной сцены; позже экраны можно перевести
/// на prefab/UI Toolkit без изменения сервисов.
///
public static class UiKit
{
private static Font _font;
public static Font DefaultFont
{
get
{
if (_font != null)
return _font;
_font = Resources.GetBuiltinResource("LegacyRuntime.ttf");
if (_font == null)
_font = Resources.GetBuiltinResource("Arial.ttf");
return _font;
}
}
public static Canvas CreateCanvas(string name)
{
EnsureEventSystem();
var go = new GameObject(name, typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
if (Application.isPlaying)
Object.DontDestroyOnLoad(go);
var canvas = go.GetComponent();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 0;
var scaler = go.GetComponent();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1920f, 1080f);
scaler.matchWidthOrHeight = 0.5f;
return canvas;
}
public static void EnsureEventSystem()
{
if (Object.FindAnyObjectByType() != null)
return;
var go = new GameObject("EventSystem", typeof(EventSystem));
if (Application.isPlaying)
Object.DontDestroyOnLoad(go);
var module = go.AddComponent();
module.AssignDefaultActions();
}
public static RectTransform CreatePanel(Transform parent, string name, Color color)
{
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
var rect = (RectTransform)go.transform;
rect.SetParent(parent, false);
Stretch(rect);
var image = go.GetComponent();
image.color = color;
image.raycastTarget = true;
return rect;
}
public static RectTransform CreateCenteredCard(
Transform parent,
string name,
Vector2 size,
Color color)
{
var rect = CreatePanel(parent, name, color);
rect.anchorMin = new Vector2(0.5f, 0.5f);
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchoredPosition = Vector2.zero;
rect.sizeDelta = size;
return rect;
}
public static VerticalLayoutGroup AddVerticalLayout(
RectTransform rect,
int padding,
int spacing)
{
var layout = rect.gameObject.AddComponent();
layout.padding = new RectOffset(padding, padding, padding, padding);
layout.spacing = spacing;
layout.childAlignment = TextAnchor.UpperCenter;
layout.childControlWidth = true;
layout.childControlHeight = true;
layout.childForceExpandWidth = true;
layout.childForceExpandHeight = false;
return layout;
}
public static HorizontalLayoutGroup AddHorizontalLayout(
RectTransform rect,
int padding,
int spacing)
{
var layout = rect.gameObject.AddComponent();
layout.padding = new RectOffset(padding, padding, padding, padding);
layout.spacing = spacing;
layout.childAlignment = TextAnchor.MiddleCenter;
layout.childControlWidth = true;
layout.childControlHeight = true;
layout.childForceExpandWidth = true;
layout.childForceExpandHeight = false;
return layout;
}
public static Text CreateText(
Transform parent,
string name,
string content,
int fontSize,
Color color,
TextAnchor alignment = TextAnchor.MiddleCenter)
{
var go = new GameObject(name, typeof(RectTransform), typeof(Text));
var rect = (RectTransform)go.transform;
rect.SetParent(parent, false);
var text = go.GetComponent();
text.font = DefaultFont;
text.text = content;
text.fontSize = fontSize;
text.color = color;
text.alignment = alignment;
text.horizontalOverflow = HorizontalWrapMode.Wrap;
text.verticalOverflow = VerticalWrapMode.Overflow;
text.raycastTarget = false;
text.supportRichText = true;
return text;
}
public static Button CreateButton(
Transform parent,
string name,
string label,
UnityEngine.Events.UnityAction onClick,
int fontSize = 24)
{
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
var rect = (RectTransform)go.transform;
rect.SetParent(parent, false);
var image = go.GetComponent();
image.color = new Color(0.20f, 0.42f, 0.78f, 1f);
image.raycastTarget = true;
var button = go.GetComponent();
button.targetGraphic = image;
button.onClick.AddListener(onClick);
var text = CreateText(rect, "Label", label, fontSize, Color.white);
Stretch(text.rectTransform);
return button;
}
public static InputField CreateInput(
Transform parent,
string name,
string placeholder,
bool password = false)
{
var go = new GameObject(
name,
typeof(RectTransform),
typeof(Image),
typeof(InputField));
var rect = (RectTransform)go.transform;
rect.SetParent(parent, false);
var background = go.GetComponent();
background.color = new Color(0.10f, 0.12f, 0.16f, 1f);
background.raycastTarget = true;
var input = go.GetComponent();
input.targetGraphic = background;
input.lineType = InputField.LineType.SingleLine;
input.contentType = password
? InputField.ContentType.Password
: InputField.ContentType.Standard;
input.characterLimit = password ? 128 : 64;
input.caretColor = Color.white;
input.customCaretColor = true;
input.selectionColor = new Color(0.20f, 0.42f, 0.78f, 0.6f);
var text = CreateText(rect, "Text", string.Empty, 22, Color.white, TextAnchor.MiddleLeft);
Stretch(text.rectTransform);
var textRect = text.rectTransform;
textRect.offsetMin = new Vector2(16f, 0f);
textRect.offsetMax = new Vector2(-16f, 0f);
text.supportRichText = false;
var hint = CreateText(rect, "Placeholder", placeholder, 22, new Color(1f, 1f, 1f, 0.45f), TextAnchor.MiddleLeft);
Stretch(hint.rectTransform);
hint.rectTransform.offsetMin = new Vector2(16f, 0f);
hint.rectTransform.offsetMax = new Vector2(-16f, 0f);
hint.supportRichText = false;
input.textComponent = text;
input.placeholder = hint;
return input;
}
public static LayoutElement SetPreferredHeight(
Component component,
float height,
float flexibleWidth = 1f)
{
var element = component.gameObject.GetComponent();
if (element == null)
element = component.gameObject.AddComponent();
element.preferredHeight = height;
element.flexibleWidth = flexibleWidth;
return element;
}
public static void Stretch(RectTransform rect)
{
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.offsetMin = Vector2.zero;
rect.offsetMax = Vector2.zero;
}
public static void SetActive(Component component, bool active)
{
if (component != null)
component.gameObject.SetActive(active);
}
}
}