using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.UI;
using UnityEngine.UI;
///
/// uGUI 조각을 코드로 만드는 공용 부품. 채팅창과 설정창이 같은 것을 쓴다.
///
/// 에셋(프리팹/스프라이트/폰트)을 하나도 만들지 않는 것이 이 프로젝트의 방침이다.
/// 이유는 ChatUiTheme 에 적어뒀다.
///
public static class ChatUiBuilder
{
///
/// 씬에 EventSystem 이 없으면 만든다. 런타임 UI 를 쓰는 쪽은 모두 이걸 먼저 부른다.
///
/// Active Input Handling 이 신규 Input System 전용이므로 모듈은
/// InputSystemUIInputModule 이어야 한다. StandaloneInputModule 은 레거시
/// UnityEngine.Input 을 쓰기 때문에 이 설정에서 예외를 던진다.
///
public static void EnsureEventSystem()
{
var existing = Object.FindFirstObjectByType();
if (existing == null)
{
var go = new GameObject("EventSystem");
existing = go.AddComponent();
var module = go.AddComponent();
// 런타임에 붙이면 액션 에셋이 비어 있어 아무 입력도 받지 못한다.
if (module.actionsAsset == null) module.AssignDefaultActions();
}
// InputField 가 IME 상태를 물을 때 레거시 Input 으로 새지 않게 막는다.
// BaseInputModule 은 BaseInput 을 "상속한" 컴포넌트를 기본값으로 고르지 않으므로
// inputOverride 에 직접 넣어야 한다.
var baseModule = existing.GetComponent();
if (baseModule != null && baseModule.inputOverride == null)
{
var safeInput = existing.GetComponent();
if (safeInput == null) safeInput = existing.gameObject.AddComponent();
baseModule.inputOverride = safeInput;
}
}
public static RectTransform NewRect(string name, Transform parent)
{
var go = new GameObject(name, typeof(RectTransform));
var rect = go.GetComponent();
rect.SetParent(parent, false);
return rect;
}
/// 부모를 가득 채우도록 늘린다.
public static void Stretch(RectTransform rect, float horizontal = 0f, float vertical = 0f)
{
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.offsetMin = new Vector2(horizontal, vertical);
rect.offsetMax = new Vector2(-horizontal, -vertical);
}
public static Image NewImage(string name, Transform parent, Sprite sprite, Color color)
{
var rect = NewRect(name, parent);
var image = rect.gameObject.AddComponent();
image.sprite = sprite;
if (sprite != null) image.type = Image.Type.Sliced;
image.color = color;
return image;
}
public static Text NewText(string name, Transform parent, string value, int fontSize, Color color)
{
var rect = NewRect(name, parent);
var text = rect.gameObject.AddComponent();
text.font = ChatUiTheme.Font;
text.fontSize = fontSize;
text.color = color;
text.text = value;
text.supportRichText = false;
// 글자가 스크롤 드래그나 버튼 클릭을 가로채지 않게 한다.
text.raycastTarget = false;
return text;
}
public static Button NewButton(string name, Transform parent, string label, int fontSize,
Color background, Color foreground)
{
var image = NewImage(name, parent, ChatUiTheme.RoundedSmall, background);
var rect = image.rectTransform;
var button = rect.gameObject.AddComponent