253 lines
8.8 KiB
C#
253 lines
8.8 KiB
C#
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.InputSystem.UI;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Vanguard.UI
|
|
{
|
|
/// <summary>
|
|
/// Минимальная фабрика uGUI. Экраны собираются кодом, чтобы каркас
|
|
/// запускался без префабов и ручной сцены; позже экраны можно перевести
|
|
/// на prefab/UI Toolkit без изменения сервисов.
|
|
/// </summary>
|
|
public static class UiKit
|
|
{
|
|
private static Font _font;
|
|
|
|
public static Font DefaultFont
|
|
{
|
|
get
|
|
{
|
|
if (_font != null)
|
|
return _font;
|
|
|
|
_font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
|
if (_font == null)
|
|
_font = Resources.GetBuiltinResource<Font>("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>();
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
canvas.sortingOrder = 0;
|
|
|
|
var scaler = go.GetComponent<CanvasScaler>();
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
|
scaler.referenceResolution = new Vector2(1920f, 1080f);
|
|
scaler.matchWidthOrHeight = 0.5f;
|
|
|
|
return canvas;
|
|
}
|
|
|
|
public static void EnsureEventSystem()
|
|
{
|
|
if (Object.FindAnyObjectByType<EventSystem>() != null)
|
|
return;
|
|
|
|
var go = new GameObject("EventSystem", typeof(EventSystem));
|
|
if (Application.isPlaying)
|
|
Object.DontDestroyOnLoad(go);
|
|
|
|
var module = go.AddComponent<InputSystemUIInputModule>();
|
|
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>();
|
|
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<VerticalLayoutGroup>();
|
|
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<HorizontalLayoutGroup>();
|
|
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>();
|
|
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>();
|
|
image.color = new Color(0.20f, 0.42f, 0.78f, 1f);
|
|
image.raycastTarget = true;
|
|
|
|
var button = go.GetComponent<Button>();
|
|
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<Image>();
|
|
background.color = new Color(0.10f, 0.12f, 0.16f, 1f);
|
|
background.raycastTarget = true;
|
|
|
|
var input = go.GetComponent<InputField>();
|
|
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<LayoutElement>();
|
|
if (element == null)
|
|
element = component.gameObject.AddComponent<LayoutElement>();
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|