573 lines
29 KiB
C#
573 lines
29 KiB
C#
using System.IO;
|
|
using AibisDream.UI.Terminal;
|
|
using TMPro;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace AibisDream.EditorTools.TerminalUI
|
|
{
|
|
public static class TerminalMainUIPrefabBuilder
|
|
{
|
|
private const string PrefabRoot = "Assets/GameContent/Feature_MainUI/Prefabs";
|
|
private const string CommonRoot = PrefabRoot + "/Common";
|
|
private const string FontPath = "Assets/Font/Assets/WenQuanYi Bitmap Song 14px SDF.asset";
|
|
private static readonly Vector2 PanelSize = new Vector2(1920f, 1080f);
|
|
private static readonly Vector2 ReferenceSize = new Vector2(768f, 432f);
|
|
private const float UiScale = 2.5f;
|
|
|
|
private static TMP_FontAsset _font;
|
|
|
|
[MenuItem("AIBIS/Terminal UI/Rebuild MainUI Prefabs")]
|
|
public static void BuildAll()
|
|
{
|
|
EnsureFolders();
|
|
_font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(FontPath);
|
|
if (_font == null)
|
|
{
|
|
Debug.LogError($"[TerminalMainUIPrefabBuilder] Font not found: {FontPath}");
|
|
return;
|
|
}
|
|
|
|
BuildCommonPrefabs();
|
|
BuildStartPanel();
|
|
BuildSettingPanel();
|
|
BuildChapterPanel();
|
|
BuildRecordPanel();
|
|
BuildLoadingPanel();
|
|
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
Debug.Log("[TerminalMainUIPrefabBuilder] Terminal MainUI prefabs rebuilt.");
|
|
}
|
|
|
|
public static void BuildAllAndInstallToPersistence()
|
|
{
|
|
BuildAll();
|
|
InstallToPersistenceScene();
|
|
}
|
|
|
|
[MenuItem("AIBIS/Terminal UI/Install MainUI Prefabs To Open Persistence")]
|
|
public static void InstallToPersistenceScene()
|
|
{
|
|
var uiCanvas = GameObject.Find("UI Canvas");
|
|
if (uiCanvas == null)
|
|
{
|
|
Debug.LogError("[TerminalMainUIPrefabBuilder] Open Persistence scene first. UI Canvas was not found.");
|
|
return;
|
|
}
|
|
|
|
InstantiateUnderCanvas("TerminalStartPanel.prefab", uiCanvas.transform, false);
|
|
InstantiateUnderCanvas("TerminalSettingPanel.prefab", uiCanvas.transform, false);
|
|
InstantiateUnderCanvas("TerminalChapterPanel.prefab", uiCanvas.transform, false);
|
|
InstantiateUnderCanvas("TerminalRecordPanel.prefab", uiCanvas.transform, false);
|
|
InstantiateUnderCanvas("TerminalLoadingPanel.prefab", uiCanvas.transform, false);
|
|
EditorSceneManager.MarkSceneDirty(uiCanvas.scene);
|
|
}
|
|
|
|
private static void BuildCommonPrefabs()
|
|
{
|
|
SavePrefab(CreateHeaderTemplate(), CommonRoot + "/TerminalHeader.prefab");
|
|
SavePrefab(CreateMenuItemTemplate(), CommonRoot + "/TerminalMenuItem.prefab");
|
|
SavePrefab(CreateSliderTemplate(), CommonRoot + "/TerminalSliderItem.prefab");
|
|
SavePrefab(CreateOptionTemplate(), CommonRoot + "/TerminalOptionItem.prefab");
|
|
SavePrefab(CreateChapterCardTemplate(), CommonRoot + "/TerminalChapterCard.prefab");
|
|
SavePrefab(CreateRecordItemTemplate(), CommonRoot + "/TerminalRecordItem.prefab");
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
private static void BuildStartPanel()
|
|
{
|
|
var root = CreatePanelRoot("TerminalStartPanel", typeof(TerminalStartPanel));
|
|
var panel = root.GetComponent<TerminalStartPanel>();
|
|
var animator = root.GetComponent<TerminalPanelAnimator>();
|
|
|
|
var header = AddHeader(root.transform, Point(384f, 21f), "<MENU>", "CHAPER xx/xxx - LOADING - DT");
|
|
AddText(root.transform, "SELECT OPERATION", 34f, TextAlignmentOptions.Left, Point(177f, 124f), Size(220f, 28f));
|
|
var newGame = AddMenuItem(root.transform, Point(384f, 173f), "NEW GAME.....", "pending", "Current date: 04/2020", false);
|
|
var chapter = AddMenuItem(root.transform, Point(384f, 197f), "CHAPTER......", "check ok", "Current date: 00/2020", false);
|
|
chapter.SetSelected(true);
|
|
var setting = AddMenuItem(root.transform, Point(384f, 221f), "SETTING......", "pending", "Current date: xx/xxxx", false);
|
|
var quit = AddMenuItem(root.transform, Point(384f, 245f), "QUIT.........", "-----", "-----: 00/0000", true);
|
|
AddSideMarks(root.transform, Point(384f, 209f).y);
|
|
AddFooter(root.transform);
|
|
|
|
SetObject(panel, "panelAnimator", animator);
|
|
SetObject(panel, "header", header);
|
|
SetObject(panel, "newGameItem", newGame);
|
|
SetObject(panel, "chapterItem", chapter);
|
|
SetObject(panel, "settingItem", setting);
|
|
SetObject(panel, "quitItem", quit);
|
|
SavePrefab(root, PrefabRoot + "/TerminalStartPanel.prefab");
|
|
}
|
|
|
|
private static void BuildSettingPanel()
|
|
{
|
|
var root = CreatePanelRoot("TerminalSettingPanel", typeof(TerminalSettingPanel));
|
|
var panel = root.GetComponent<TerminalSettingPanel>();
|
|
var animator = root.GetComponent<TerminalPanelAnimator>();
|
|
|
|
var header = AddHeader(root.transform, Point(384f, 21f), "<SETTING>", "MUSIC 50/100 - AUDIO INPUT 001");
|
|
AddText(root.transform, "SELECT OPERATION", 34f, TextAlignmentOptions.Left, Point(177f, 76f), Size(220f, 28f));
|
|
var volume = AddSlider(root.transform, Point(384f, 109f));
|
|
var windowMode = AddOption(root.transform, Point(360f, 133f));
|
|
var textSpeed = AddSlider(root.transform, Point(384f, 157f));
|
|
var language = AddOption(root.transform, Point(360f, 181f));
|
|
var continueButton = AddTextButton(root.transform, "CONTINUE", Point(228f, 365f), false);
|
|
var backButton = AddTextButton(root.transform, "MAIN MENU", Point(384f, 365f), false);
|
|
var quitButton = AddTextButton(root.transform, "QUIT", Point(540f, 365f), true);
|
|
AddSideMarks(root.transform, Point(384f, 209f).y);
|
|
AddFooter(root.transform);
|
|
|
|
SetObject(panel, "panelAnimator", animator);
|
|
SetObject(panel, "header", header);
|
|
SetObject(panel, "volumeSlider", volume);
|
|
SetObject(panel, "textSpeedSlider", textSpeed);
|
|
SetObject(panel, "windowModeOption", windowMode);
|
|
SetObject(panel, "languageOption", language);
|
|
SetObject(panel, "continueButton", continueButton);
|
|
SetObject(panel, "backToMainButton", backButton);
|
|
SetObject(panel, "quitButton", quitButton);
|
|
SavePrefab(root, PrefabRoot + "/TerminalSettingPanel.prefab");
|
|
}
|
|
|
|
private static void BuildChapterPanel()
|
|
{
|
|
var root = CreatePanelRoot("TerminalChapterPanel", typeof(TerminalChapterPanel));
|
|
var panel = root.GetComponent<TerminalChapterPanel>();
|
|
var animator = root.GetComponent<TerminalPanelAnimator>();
|
|
|
|
var header = AddHeader(root.transform, Point(384f, 21f), "<CHAPTER>", string.Empty);
|
|
var left = AddChapterCard(root.transform, Point(173f, 171f), Size(106f, 106f));
|
|
var current = AddChapterCard(root.transform, Point(384f, 176f), Size(235f, 235f));
|
|
var right = AddChapterCard(root.transform, Point(595f, 171f), Size(106f, 106f));
|
|
var empty = AddText(root.transform, "NO CHAPTER DATA", 34f, TextAlignmentOptions.Center, Vector2.zero, Size(240f, 32f));
|
|
var selectedTitle = AddText(root.transform, "CHAPTER TITLE", 32f, TextAlignmentOptions.Center, Point(384f, 320f), Size(210f, 28f));
|
|
var previousButton = AddTextButton(root.transform, "<", Point(312f, 320f), false);
|
|
var nextButton = AddTextButton(root.transform, ">", Point(456f, 320f), false);
|
|
var restartButton = AddTextButton(root.transform, "RESTART", Point(384f, 356f), false);
|
|
var backButton = AddTextButton(root.transform, "BACK", Point(384f, 368f), true);
|
|
AddSideMarks(root.transform, Point(384f, 209f).y);
|
|
AddFooter(root.transform);
|
|
|
|
SetObject(panel, "panelAnimator", animator);
|
|
SetObject(panel, "header", header);
|
|
SetObject(panel, "leftPreview", left);
|
|
SetObject(panel, "currentView", current);
|
|
SetObject(panel, "rightPreview", right);
|
|
SetObject(panel, "emptyText", empty);
|
|
SetObject(panel, "selectedTitleText", selectedTitle);
|
|
SetObject(panel, "previousButton", previousButton);
|
|
SetObject(panel, "nextButton", nextButton);
|
|
SetObject(panel, "restartButton", restartButton);
|
|
SetObject(panel, "backButton", backButton);
|
|
SavePrefab(root, PrefabRoot + "/TerminalChapterPanel.prefab");
|
|
}
|
|
|
|
private static void BuildRecordPanel()
|
|
{
|
|
var root = CreatePanelRoot("TerminalRecordPanel", typeof(TerminalRecordPanel));
|
|
var panel = root.GetComponent<TerminalRecordPanel>();
|
|
var animator = root.GetComponent<TerminalPanelAnimator>();
|
|
|
|
var header = AddHeader(root.transform, Point(384f, 21f), "<CLINICAL RECORD>", "EMR 511/42 - Clinical Record");
|
|
var viewport = CreateUIObject("Record Scroll", root.transform, Point(384f, 188f), Size(410f, 245f));
|
|
var scrollRect = viewport.AddComponent<ScrollRect>();
|
|
var mask = viewport.AddComponent<Mask>();
|
|
mask.showMaskGraphic = false;
|
|
var viewportImage = viewport.AddComponent<Image>();
|
|
viewportImage.color = new Color(1f, 1f, 1f, 0.001f);
|
|
var content = CreateUIObject("Content", viewport.transform, Vector2.zero, Size(410f, 245f));
|
|
var layout = content.AddComponent<VerticalLayoutGroup>();
|
|
layout.spacing = 18f;
|
|
layout.childControlHeight = true;
|
|
layout.childControlWidth = true;
|
|
layout.childForceExpandHeight = false;
|
|
layout.childForceExpandWidth = true;
|
|
content.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
scrollRect.viewport = viewport.GetComponent<RectTransform>();
|
|
scrollRect.content = content.GetComponent<RectTransform>();
|
|
scrollRect.horizontal = false;
|
|
var emptyText = AddText(viewport.transform, "NO CLINICAL RECORD", 30f, TextAlignmentOptions.Center, Vector2.zero, Size(260f, 30f));
|
|
var backButton = AddTextButton(root.transform, "BACK", Point(384f, 368f), true);
|
|
var itemPrefabObject = AssetDatabase.LoadAssetAtPath<GameObject>(CommonRoot + "/TerminalRecordItem.prefab");
|
|
var itemPrefab = itemPrefabObject != null ? itemPrefabObject.GetComponent<TerminalRecordItemView>() : null;
|
|
AddSideMarks(root.transform, Point(384f, 209f).y);
|
|
|
|
SetObject(panel, "panelAnimator", animator);
|
|
SetObject(panel, "header", header);
|
|
SetObject(panel, "backButton", backButton);
|
|
SetObject(panel, "scrollRect", scrollRect);
|
|
SetObject(panel, "recordRoot", content.transform);
|
|
SetObject(panel, "recordItemPrefab", itemPrefab);
|
|
SetObject(panel, "emptyText", emptyText);
|
|
SavePrefab(root, PrefabRoot + "/TerminalRecordPanel.prefab");
|
|
}
|
|
|
|
private static void BuildLoadingPanel()
|
|
{
|
|
var root = CreatePanelRoot("TerminalLoadingPanel", typeof(TerminalLoadingPanel));
|
|
var panel = root.GetComponent<TerminalLoadingPanel>();
|
|
var animator = root.GetComponent<TerminalPanelAnimator>();
|
|
|
|
var avatar = CreateUIObject("Avatar", root.transform, Point(248f, 160f), Size(100f, 100f)).AddComponent<Image>();
|
|
avatar.color = new Color(1f, 1f, 1f, 0.08f);
|
|
var company = AddText(root.transform, "SATISFYING INC", 32f, TextAlignmentOptions.Left, Point(444f, 116f), Size(220f, 28f));
|
|
var device = AddText(root.transform, "Device Model: Dell P5999 DX130\nDevice Serial Number: SN46456546DAS", 24f, TextAlignmentOptions.Left, Point(472f, 145f), Size(330f, 42f));
|
|
var user = AddText(root.transform, "User Name: Luth\nUser Title: DOC.\nEmployee ID: D42", 24f, TextAlignmentOptions.Left, Point(444f, 192f), Size(260f, 58f));
|
|
var bar = CreateUIObject("Progress Bar", root.transform, Point(384f, 244f), Size(374f, 12f)).AddComponent<Image>();
|
|
bar.color = Color.white;
|
|
var fill = CreateUIObject("Fill", bar.transform, Vector2.zero, Size(374f, 12f)).AddComponent<Image>();
|
|
fill.color = Color.white;
|
|
var fillRect = fill.GetComponent<RectTransform>();
|
|
fillRect.anchorMin = new Vector2(0f, 0f);
|
|
fillRect.anchorMax = new Vector2(0f, 1f);
|
|
fillRect.offsetMin = Vector2.zero;
|
|
fillRect.offsetMax = Vector2.zero;
|
|
var loading = AddText(root.transform, "LOADING...", 28f, TextAlignmentOptions.Center, Point(384f, 266f), Size(120f, 24f));
|
|
AddText(root.transform, "AM **:**\nWE.92 2650", 24f, TextAlignmentOptions.Left, Point(390f, 352f), Size(120f, 45f));
|
|
AddSideMarks(root.transform, Point(384f, 209f).y);
|
|
|
|
SetObject(panel, "panelAnimator", animator);
|
|
SetObject(panel, "companyText", company);
|
|
SetObject(panel, "deviceText", device);
|
|
SetObject(panel, "userText", user);
|
|
SetObject(panel, "loadingText", loading);
|
|
SetObject(panel, "avatarImage", avatar);
|
|
SetObject(panel, "progressFill", fillRect);
|
|
SavePrefab(root, PrefabRoot + "/TerminalLoadingPanel.prefab");
|
|
}
|
|
|
|
private static GameObject CreatePanelRoot(string name, System.Type panelType)
|
|
{
|
|
var root = CreateUIObject(name, null, Vector2.zero, PanelSize);
|
|
var rect = root.GetComponent<RectTransform>();
|
|
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
|
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
|
rect.sizeDelta = PanelSize;
|
|
|
|
var canvasGroup = root.AddComponent<CanvasGroup>();
|
|
var animator = root.AddComponent<TerminalPanelAnimator>();
|
|
root.AddComponent(panelType);
|
|
SetObject(animator, "canvasGroup", canvasGroup);
|
|
root.SetActive(false);
|
|
return root;
|
|
}
|
|
|
|
private static TerminalHeaderView AddHeader(Transform parent, Vector2 pos, string title, string status)
|
|
{
|
|
var go = InstantiateCommon("TerminalHeader.prefab", parent);
|
|
SetRect(go, pos, Size(415f, 17f));
|
|
var header = go.GetComponent<TerminalHeaderView>();
|
|
header.SetText(title, status);
|
|
return header;
|
|
}
|
|
|
|
private static TerminalMenuItemView AddMenuItem(Transform parent, Vector2 pos, string label, string status, string detail, bool danger)
|
|
{
|
|
var go = InstantiateCommon("TerminalMenuItem.prefab", parent);
|
|
SetRect(go, pos, Size(415f, 18f));
|
|
var view = go.GetComponent<TerminalMenuItemView>();
|
|
view.SetContent(label, status, detail, danger);
|
|
return view;
|
|
}
|
|
|
|
private static TerminalSliderView AddSlider(Transform parent, Vector2 pos)
|
|
{
|
|
var go = InstantiateCommon("TerminalSliderItem.prefab", parent);
|
|
SetRect(go, pos, Size(410f, 18f));
|
|
return go.GetComponent<TerminalSliderView>();
|
|
}
|
|
|
|
private static TerminalOptionItemView AddOption(Transform parent, Vector2 pos)
|
|
{
|
|
var go = InstantiateCommon("TerminalOptionItem.prefab", parent);
|
|
SetRect(go, pos, Size(250f, 18f));
|
|
return go.GetComponent<TerminalOptionItemView>();
|
|
}
|
|
|
|
private static TerminalChapterItemView AddChapterCard(Transform parent, Vector2 pos, Vector2 size)
|
|
{
|
|
var go = InstantiateCommon("TerminalChapterCard.prefab", parent);
|
|
SetRect(go, pos, size);
|
|
return go.GetComponent<TerminalChapterItemView>();
|
|
}
|
|
|
|
private static Button AddTextButton(Transform parent, string text, Vector2 pos, bool danger)
|
|
{
|
|
var go = CreateUIObject(text + " Button", parent, pos, Size(100f, 22f));
|
|
var button = AddTransparentBaseButton(go);
|
|
CreateLine(go.transform, "Top Line", new Vector2(0f, 20f), Size(100f, 1f));
|
|
CreateLine(go.transform, "Bottom Line", new Vector2(0f, -20f), Size(100f, 1f));
|
|
AddText(go.transform, text, 28f, TextAlignmentOptions.Center, Vector2.zero, Size(100f, 18f), danger ? new Color(1f, 0.18f, 0.2f) : Color.white);
|
|
return button;
|
|
}
|
|
|
|
private static void AddFooter(Transform parent)
|
|
{
|
|
AddText(parent, "Please keep this device secure. Do not lose, transfer, or remove it from the premises without authorization.\nUnauthorized use of this device is strictly prohibited.", 13f, TextAlignmentOptions.Left, Point(384f, 385f), Size(325f, 24f));
|
|
}
|
|
|
|
private static void AddSideMarks(Transform parent, float y)
|
|
{
|
|
CreateLine(parent, "Left Mark", new Vector2(Point(68f, 216f).x, y), Size(96f, 1f));
|
|
CreateLine(parent, "Right Mark", new Vector2(Point(700f, 216f).x, y), Size(96f, 1f));
|
|
}
|
|
|
|
private static GameObject CreateHeaderTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalHeader", null, Vector2.zero, Size(415f, 17f));
|
|
var bg = root.AddComponent<Image>();
|
|
bg.color = Color.white;
|
|
var title = AddText(root.transform, "<TITLE>", 28f, TextAlignmentOptions.Left, new Vector2(-275f, 0f), Size(100f, 17f), Color.black);
|
|
var status = AddText(root.transform, "STATUS", 28f, TextAlignmentOptions.Left, new Vector2(75f, 0f), Size(270f, 17f), Color.black);
|
|
var header = root.AddComponent<TerminalHeaderView>();
|
|
SetObject(header, "titleText", title);
|
|
SetObject(header, "statusText", status);
|
|
return root;
|
|
}
|
|
|
|
private static GameObject CreateMenuItemTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalMenuItem", null, Vector2.zero, Size(415f, 18f));
|
|
AddTransparentBaseButton(root);
|
|
var bar = CreateUIObject("Selection Bar", root.transform, new Vector2(0f, 0f), Size(415f, 16f)).AddComponent<Image>();
|
|
bar.color = Color.white;
|
|
bar.raycastTarget = false;
|
|
var cursor = AddText(root.transform, ">", 28f, TextAlignmentOptions.Center, new Vector2(-497f, 0f), Size(16f, 16f));
|
|
var label = AddText(root.transform, "Label", 28f, TextAlignmentOptions.Left, new Vector2(-342f, 0f), Size(128f, 16f));
|
|
var status = AddText(root.transform, "Status", 28f, TextAlignmentOptions.Left, new Vector2(-95f, 0f), Size(95f, 16f));
|
|
var detail = AddText(root.transform, "Detail", 18f, TextAlignmentOptions.Left, new Vector2(245f, 0f), Size(200f, 16f));
|
|
var view = root.AddComponent<TerminalMenuItemView>();
|
|
SetObject(view, "labelText", label);
|
|
SetObject(view, "statusText", status);
|
|
SetObject(view, "detailText", detail);
|
|
SetObject(view, "cursor", cursor);
|
|
SetObject(view, "selectionBar", bar);
|
|
return root;
|
|
}
|
|
|
|
private static GameObject CreateSliderTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalSliderItem", null, Vector2.zero, Size(410f, 18f));
|
|
var label = AddText(root.transform, "Label", 28f, TextAlignmentOptions.Left, new Vector2(-330f, 0f), Size(100f, 16f));
|
|
var value = AddText(root.transform, "50/100", 28f, TextAlignmentOptions.Left, new Vector2(-130f, 0f), Size(70f, 16f));
|
|
var sliderObject = CreateUIObject("Slider", root.transform, new Vector2(165f, 0f), Size(200f, 12f));
|
|
var slider = sliderObject.AddComponent<Slider>();
|
|
slider.transition = Selectable.Transition.None;
|
|
var bg = CreateUIObject("Background", sliderObject.transform, Vector2.zero, Size(200f, 11f)).AddComponent<Image>();
|
|
bg.color = new Color(1f, 1f, 1f, 0.08f);
|
|
var fill = CreateUIObject("Fill", sliderObject.transform, Vector2.zero, Size(200f, 11f)).AddComponent<Image>();
|
|
fill.color = Color.white;
|
|
var handle = CreateUIObject("Handle", sliderObject.transform, Vector2.zero, Size(5f, 12f)).AddComponent<Image>();
|
|
handle.color = Color.white;
|
|
slider.fillRect = fill.GetComponent<RectTransform>();
|
|
slider.handleRect = handle.GetComponent<RectTransform>();
|
|
var view = root.AddComponent<TerminalSliderView>();
|
|
SetObject(view, "labelText", label);
|
|
SetObject(view, "valueText", value);
|
|
SetObject(view, "slider", slider);
|
|
SetObject(view, "fillRect", fill.GetComponent<RectTransform>());
|
|
return root;
|
|
}
|
|
|
|
private static GameObject CreateOptionTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalOptionItem", null, Vector2.zero, Size(250f, 18f));
|
|
var label = AddText(root.transform, "Label", 28f, TextAlignmentOptions.Left, new Vector2(-205f, 0f), Size(100f, 16f));
|
|
var value = AddText(root.transform, "<Value>", 28f, TextAlignmentOptions.Left, new Vector2(45f, 0f), Size(120f, 16f));
|
|
var prev = CreateTinyButton(root.transform, "<", new Vector2(-35f, 0f));
|
|
var next = CreateTinyButton(root.transform, ">", new Vector2(270f, 0f));
|
|
var view = root.AddComponent<TerminalOptionItemView>();
|
|
SetObject(view, "labelText", label);
|
|
SetObject(view, "valueText", value);
|
|
SetObject(view, "previousButton", prev);
|
|
SetObject(view, "nextButton", next);
|
|
return root;
|
|
}
|
|
|
|
private static GameObject CreateChapterCardTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalChapterCard", null, Vector2.zero, Size(140f, 120f));
|
|
AddTransparentBaseButton(root);
|
|
var cover = CreateUIObject("Cover", root.transform, new Vector2(0f, 25f), Size(120f, 80f)).AddComponent<Image>();
|
|
cover.color = new Color(1f, 1f, 1f, 0.2f);
|
|
cover.raycastTarget = false;
|
|
var frame = CreateUIObject("Selection Frame", root.transform, new Vector2(0f, 25f), Size(125f, 85f)).AddComponent<Image>();
|
|
frame.color = new Color(1f, 1f, 1f, 0.16f);
|
|
frame.raycastTarget = false;
|
|
var title = AddText(root.transform, "Title", 26f, TextAlignmentOptions.Center, new Vector2(0f, -95f), Size(120f, 18f));
|
|
var chapter = AddText(root.transform, "Chapter", 20f, TextAlignmentOptions.Center, new Vector2(0f, -125f), Size(120f, 16f));
|
|
var status = AddText(root.transform, "PENDING", 16f, TextAlignmentOptions.Center, new Vector2(0f, -150f), Size(120f, 14f));
|
|
var view = root.AddComponent<TerminalChapterItemView>();
|
|
SetObject(view, "coverImage", cover);
|
|
SetObject(view, "titleText", title);
|
|
SetObject(view, "chapterText", chapter);
|
|
SetObject(view, "statusText", status);
|
|
SetObject(view, "selectionFrame", frame);
|
|
return root;
|
|
}
|
|
|
|
private static GameObject CreateRecordItemTemplate()
|
|
{
|
|
var root = CreateUIObject("TerminalRecordItem", null, Vector2.zero, Size(410f, 32f));
|
|
var layout = root.AddComponent<HorizontalLayoutGroup>();
|
|
layout.spacing = 24f;
|
|
layout.childControlHeight = true;
|
|
layout.childControlWidth = false;
|
|
layout.childForceExpandHeight = false;
|
|
layout.childForceExpandWidth = false;
|
|
var actor = AddText(root.transform, "Actor", 24f, TextAlignmentOptions.TopLeft, Vector2.zero, Size(55f, 30f));
|
|
actor.gameObject.AddComponent<LayoutElement>().preferredWidth = Size(55f, 1f).x;
|
|
var line = AddText(root.transform, "Record line", 24f, TextAlignmentOptions.TopLeft, Vector2.zero, Size(330f, 30f));
|
|
line.gameObject.AddComponent<LayoutElement>().preferredWidth = Size(330f, 1f).x;
|
|
var view = root.AddComponent<TerminalRecordItemView>();
|
|
SetObject(view, "actorNameText", actor);
|
|
SetObject(view, "lineText", line);
|
|
return root;
|
|
}
|
|
|
|
private static Button CreateTinyButton(Transform parent, string text, Vector2 pos)
|
|
{
|
|
var go = CreateUIObject(text + " Button", parent, pos, Size(18f, 18f));
|
|
var button = AddTransparentBaseButton(go);
|
|
AddText(go.transform, text, 24f, TextAlignmentOptions.Center, Vector2.zero, Size(18f, 18f));
|
|
return button;
|
|
}
|
|
|
|
private static TMP_Text AddText(Transform parent, string text, float size, TextAlignmentOptions alignment, Vector2 pos, Vector2 rectSize)
|
|
{
|
|
return AddText(parent, text, size, alignment, pos, rectSize, Color.white);
|
|
}
|
|
|
|
private static TMP_Text AddText(Transform parent, string text, float size, TextAlignmentOptions alignment, Vector2 pos, Vector2 rectSize, Color color)
|
|
{
|
|
var go = CreateUIObject("Text", parent, pos, rectSize);
|
|
var tmp = go.AddComponent<TextMeshProUGUI>();
|
|
tmp.font = _font;
|
|
tmp.fontSize = size;
|
|
tmp.alignment = alignment;
|
|
tmp.color = color;
|
|
tmp.text = text;
|
|
tmp.raycastTarget = false;
|
|
return tmp;
|
|
}
|
|
|
|
private static Image CreateLine(Transform parent, string name, Vector2 pos, Vector2 size)
|
|
{
|
|
var line = CreateUIObject(name, parent, pos, size).AddComponent<Image>();
|
|
line.color = Color.white;
|
|
line.raycastTarget = false;
|
|
return line;
|
|
}
|
|
|
|
private static BaseButton AddTransparentBaseButton(GameObject go)
|
|
{
|
|
var hitArea = go.AddComponent<Image>();
|
|
hitArea.color = new Color(1f, 1f, 1f, 0.001f);
|
|
hitArea.raycastTarget = true;
|
|
|
|
var button = go.AddComponent<BaseButton>();
|
|
button.targetGraphic = hitArea;
|
|
button.transition = Selectable.Transition.None;
|
|
return button;
|
|
}
|
|
|
|
private static GameObject InstantiateCommon(string prefabName, Transform parent)
|
|
{
|
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>($"{CommonRoot}/{prefabName}");
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogError($"[TerminalMainUIPrefabBuilder] Missing common prefab: {prefabName}");
|
|
return CreateUIObject(prefabName, parent, Vector2.zero, Vector2.one);
|
|
}
|
|
|
|
var instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
|
|
instance.transform.SetParent(parent, false);
|
|
return instance;
|
|
}
|
|
|
|
private static GameObject CreateUIObject(string name, Transform parent, Vector2 anchoredPosition, Vector2 size)
|
|
{
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|
if (parent != null)
|
|
{
|
|
go.transform.SetParent(parent, false);
|
|
}
|
|
|
|
SetRect(go, anchoredPosition, size);
|
|
return go;
|
|
}
|
|
|
|
private static void SetRect(GameObject go, Vector2 anchoredPosition, Vector2 size)
|
|
{
|
|
var rect = go.GetComponent<RectTransform>();
|
|
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 = anchoredPosition;
|
|
rect.sizeDelta = size;
|
|
}
|
|
|
|
private static Vector2 Point(float x, float y)
|
|
{
|
|
return new Vector2((x - ReferenceSize.x * 0.5f) * UiScale, (ReferenceSize.y * 0.5f - y) * UiScale);
|
|
}
|
|
|
|
private static Vector2 Size(float width, float height)
|
|
{
|
|
return new Vector2(width * UiScale, height * UiScale);
|
|
}
|
|
|
|
private static void SetObject(Object target, string propertyName, Object value)
|
|
{
|
|
var serializedObject = new SerializedObject(target);
|
|
var property = serializedObject.FindProperty(propertyName);
|
|
if (property == null)
|
|
{
|
|
Debug.LogError($"[TerminalMainUIPrefabBuilder] Missing property {propertyName} on {target.name}");
|
|
return;
|
|
}
|
|
|
|
property.objectReferenceValue = value;
|
|
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
|
}
|
|
|
|
private static void SavePrefab(GameObject go, string path)
|
|
{
|
|
PrefabUtility.SaveAsPrefabAsset(go, path);
|
|
Object.DestroyImmediate(go);
|
|
}
|
|
|
|
private static void InstantiateUnderCanvas(string prefabName, Transform canvas, bool active)
|
|
{
|
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>($"{PrefabRoot}/{prefabName}");
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogError($"[TerminalMainUIPrefabBuilder] Missing prefab {prefabName}");
|
|
return;
|
|
}
|
|
|
|
if (canvas.Find(prefab.name) != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, canvas);
|
|
var rect = instance.GetComponent<RectTransform>();
|
|
rect.anchorMin = Vector2.zero;
|
|
rect.anchorMax = Vector2.one;
|
|
rect.offsetMin = Vector2.zero;
|
|
rect.offsetMax = Vector2.zero;
|
|
instance.SetActive(active);
|
|
}
|
|
|
|
private static void EnsureFolders()
|
|
{
|
|
Directory.CreateDirectory(PrefabRoot);
|
|
Directory.CreateDirectory(CommonRoot);
|
|
}
|
|
}
|
|
}
|