#if UNITY_EDITOR using System.Linq; using TMPro; using UnityEditor; using UnityEngine; using UnityEngine.UI; namespace MegaKoop.EditorTools { internal static class UGUIBuilderUtils { internal static GameObject CreatePanel(Transform parent, string name, Vector2 size) { var go = new GameObject(name, typeof(RectTransform), typeof(Image)); go.transform.SetParent(parent, false); var rt = (RectTransform)go.transform; rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0.5f); rt.pivot = new Vector2(0.5f, 0.5f); rt.sizeDelta = size; var img = go.GetComponent(); img.color = new Color(0.13f, 0.13f, 0.13f, 0.95f); return go; } internal static GameObject CreateVerticalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding) { var go = new GameObject(name, typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter)); go.transform.SetParent(parent, false); var rt = (RectTransform)go.transform; rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 1); rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero; var vlg = go.GetComponent(); vlg.spacing = spacing; vlg.childAlignment = align; vlg.padding = padding; vlg.childForceExpandWidth = true; vlg.childControlWidth = true; vlg.childControlHeight = false; var fitter = go.GetComponent(); fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; return go; } internal static GameObject CreateHorizontalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding) { var go = new GameObject(name, typeof(RectTransform), typeof(HorizontalLayoutGroup)); go.transform.SetParent(parent, false); var rt = (RectTransform)go.transform; rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 0); rt.pivot = new Vector2(0.5f, 0.5f); rt.sizeDelta = new Vector2(0, 60); var hlg = go.GetComponent(); hlg.spacing = spacing; hlg.childAlignment = align; hlg.padding = padding; hlg.childControlWidth = true; hlg.childForceExpandWidth = true; return go; } internal static GameObject CreateText(Transform parent, string name, string text, int fontSize, TextAnchor anchor, Color color, FontStyles fontStyle) { var go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement)); go.transform.SetParent(parent, false); var tmp = go.GetComponent(); tmp.text = text; tmp.fontSize = fontSize; tmp.color = color; tmp.alignment = MapAlignment(anchor); tmp.fontStyle = fontStyle; tmp.enableWordWrapping = false; tmp.raycastTarget = false; if (TMP_Settings.defaultFontAsset != null) { tmp.font = TMP_Settings.defaultFontAsset; } var le = go.GetComponent(); le.minHeight = Mathf.Max(24, fontSize + 12); var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(0, fontSize + 20); return go; } private static TextAlignmentOptions MapAlignment(TextAnchor anchor) { switch (anchor) { case TextAnchor.UpperLeft: return TextAlignmentOptions.TopLeft; case TextAnchor.UpperCenter: return TextAlignmentOptions.Top; case TextAnchor.UpperRight: return TextAlignmentOptions.TopRight; case TextAnchor.MiddleLeft: return TextAlignmentOptions.MidlineLeft; case TextAnchor.MiddleCenter: return TextAlignmentOptions.Midline; case TextAnchor.MiddleRight: return TextAlignmentOptions.MidlineRight; case TextAnchor.LowerLeft: return TextAlignmentOptions.BottomLeft; case TextAnchor.LowerCenter: return TextAlignmentOptions.Bottom; case TextAnchor.LowerRight: return TextAlignmentOptions.BottomRight; default: return TextAlignmentOptions.Center; } } internal static GameObject CreateMenuButton(Transform parent, string name, string label, bool isDanger = false) { var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button)); go.transform.SetParent(parent, false); var img = go.GetComponent(); img.color = isDanger ? new Color(0.5f, 0.15f, 0.15f, 0.9f) : new Color(0.25f, 0.5f, 0.25f, 0.9f); var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(0, 48); var leBtn = go.AddComponent(); leBtn.flexibleWidth = 1; leBtn.minHeight = 48; var text = CreateText(go.transform, "Text", label, 20, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold); var textRT = (RectTransform)text.transform; textRT.anchorMin = new Vector2(0, 0); textRT.anchorMax = new Vector2(1, 1); textRT.offsetMin = Vector2.zero; textRT.offsetMax = Vector2.zero; return go; } internal static GameObject CreateInputField(Transform parent, string name, string placeholder) { var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_InputField)); go.transform.SetParent(parent, false); var img = go.GetComponent(); img.color = new Color(0.1f, 0.1f, 0.1f, 0.9f); var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 50); var viewport = new GameObject("TextViewport", typeof(RectTransform)); viewport.transform.SetParent(go.transform, false); var viewportRT = (RectTransform)viewport.transform; viewportRT.anchorMin = new Vector2(0, 0); viewportRT.anchorMax = new Vector2(1, 1); viewportRT.offsetMin = new Vector2(10, 6); viewportRT.offsetMax = new Vector2(-10, -6); var text = CreateText(viewport.transform, "Text", string.Empty, 20, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal); var placeholderGO = CreateText(viewport.transform, "Placeholder", placeholder, 18, TextAnchor.MiddleLeft, new Color(0.7f, 0.7f, 0.7f), FontStyles.Italic); var input = go.GetComponent(); input.textViewport = viewportRT; input.textComponent = text.GetComponent(); input.placeholder = placeholderGO.GetComponent(); var tRT = (RectTransform)text.transform; tRT.anchorMin = new Vector2(0, 0); tRT.anchorMax = new Vector2(1, 1); tRT.offsetMin = new Vector2(10, 0); tRT.offsetMax = new Vector2(-10, 0); var pRT = (RectTransform)placeholderGO.transform; pRT.anchorMin = new Vector2(0, 0); pRT.anchorMax = new Vector2(1, 1); pRT.offsetMin = new Vector2(10, 0); pRT.offsetMax = new Vector2(-10, 0); return go; } internal static GameObject CreateDropdown(Transform parent, string name, string[] options) { var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_Dropdown)); go.transform.SetParent(parent, false); var img = go.GetComponent(); img.color = new Color(0.2f, 0.2f, 0.2f, 0.9f); var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 50); var caption = CreateText(go.transform, "Label", options.FirstOrDefault() ?? "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal); var arrow = CreateText(go.transform, "Arrow", "▼", 18, TextAnchor.MiddleRight, Color.white, FontStyles.Bold); var template = new GameObject("Template", typeof(RectTransform), typeof(Image), typeof(ScrollRect)); template.transform.SetParent(go.transform, false); var templateRT = (RectTransform)template.transform; templateRT.anchorMin = new Vector2(0, 0); templateRT.anchorMax = new Vector2(1, 0); templateRT.pivot = new Vector2(0.5f, 1f); templateRT.sizeDelta = new Vector2(0, 220); template.SetActive(false); var templateImg = template.GetComponent(); templateImg.color = new Color(0.1f, 0.1f, 0.1f, 0.95f); var tplCanvas = template.GetComponent(); if (tplCanvas == null) { tplCanvas = template.AddComponent(); } tplCanvas.overrideSorting = true; tplCanvas.sortingOrder = 5000; if (!template.GetComponent()) { template.AddComponent(); } var viewport = new GameObject("Viewport", typeof(RectTransform), typeof(Mask), typeof(Image)); viewport.transform.SetParent(template.transform, false); var viewportRT = (RectTransform)viewport.transform; viewportRT.anchorMin = new Vector2(0, 0); viewportRT.anchorMax = new Vector2(1, 1); viewportRT.offsetMin = Vector2.zero; viewportRT.offsetMax = Vector2.zero; var vImg = viewport.GetComponent(); vImg.color = new Color(0, 0, 0, 0.2f); vImg.raycastTarget = false; var mask = viewport.GetComponent(); mask.showMaskGraphic = false; var content = new GameObject("Content", typeof(RectTransform), typeof(VerticalLayoutGroup)); content.transform.SetParent(viewport.transform, false); var contentRT = (RectTransform)content.transform; contentRT.anchorMin = new Vector2(0, 1); contentRT.anchorMax = new Vector2(1, 1); contentRT.pivot = new Vector2(0.5f, 1f); var vlg = content.GetComponent(); vlg.spacing = 4; vlg.childForceExpandWidth = true; vlg.childControlHeight = true; var item = new GameObject("Item", typeof(RectTransform), typeof(Toggle)); item.transform.SetParent(content.transform, false); var itemRT = (RectTransform)item.transform; itemRT.sizeDelta = new Vector2(0, 30); var itemBG = new GameObject("Item Background", typeof(RectTransform), typeof(Image)); itemBG.transform.SetParent(item.transform, false); var itemBGImg = itemBG.GetComponent(); itemBGImg.color = new Color(0.2f, 0.2f, 0.2f, 0.9f); var itemCheck = new GameObject("Item Checkmark", typeof(RectTransform), typeof(Image)); itemCheck.transform.SetParent(itemBG.transform, false); var itemCheckImg = itemCheck.GetComponent(); itemCheckImg.color = new Color(0.7f, 1f, 0.7f, 1f); var itemLabelGO = CreateText(item.transform, "Item Label", "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal); var bgRT = (RectTransform)itemBG.transform; bgRT.anchorMin = new Vector2(0, 0); bgRT.anchorMax = new Vector2(1, 1); bgRT.offsetMin = Vector2.zero; bgRT.offsetMax = Vector2.zero; var ckRT = (RectTransform)itemCheck.transform; ckRT.anchorMin = new Vector2(0, 0.5f); ckRT.anchorMax = new Vector2(0, 0.5f); ckRT.pivot = new Vector2(0, 0.5f); ckRT.sizeDelta = new Vector2(18, 18); ckRT.anchoredPosition = new Vector2(6, 0); var itemLabelRT = (RectTransform)itemLabelGO.transform; itemLabelRT.anchorMin = new Vector2(0, 0); itemLabelRT.anchorMax = new Vector2(1, 1); itemLabelRT.offsetMin = new Vector2(28, 0); itemLabelRT.offsetMax = new Vector2(-6, 0); var toggle = item.GetComponent(); toggle.targetGraphic = itemBGImg; toggle.graphic = itemCheckImg; var dropdown = go.GetComponent(); dropdown.template = templateRT; dropdown.captionText = caption.GetComponent(); dropdown.itemText = itemLabelGO.GetComponent(); dropdown.options = options.Select(o => new TMP_Dropdown.OptionData(o)).ToList(); dropdown.alphaFadeSpeed = 0.15f; dropdown.RefreshShownValue(); var scrollRect = template.GetComponent(); scrollRect.viewport = viewportRT; scrollRect.content = (RectTransform)content.transform; scrollRect.horizontal = false; scrollRect.vertical = true; return go; } internal static GameObject CreateSlider(Transform parent, string name, float min, float max, float value) { var go = new GameObject(name, typeof(RectTransform), typeof(Slider)); go.transform.SetParent(parent, false); var slider = go.GetComponent(); slider.minValue = min; slider.maxValue = max; slider.value = value; slider.direction = Slider.Direction.LeftToRight; slider.wholeNumbers = true; var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 30); var background = new GameObject("Background", typeof(RectTransform), typeof(Image)); background.transform.SetParent(go.transform, false); var bgRT = (RectTransform)background.transform; bgRT.anchorMin = new Vector2(0, 0.25f); bgRT.anchorMax = new Vector2(1, 0.75f); bgRT.offsetMin = Vector2.zero; bgRT.offsetMax = Vector2.zero; var bgImg = background.GetComponent(); bgImg.color = new Color(0.1f, 0.1f, 0.1f, 1f); var fillArea = new GameObject("Fill Area", typeof(RectTransform)); fillArea.transform.SetParent(go.transform, false); var faRT = (RectTransform)fillArea.transform; faRT.anchorMin = new Vector2(0, 0.25f); faRT.anchorMax = new Vector2(1, 0.75f); faRT.offsetMin = new Vector2(10, 0); faRT.offsetMax = new Vector2(-10, 0); var fill = new GameObject("Fill", typeof(RectTransform), typeof(Image)); fill.transform.SetParent(fillArea.transform, false); var fillImg = fill.GetComponent(); fillImg.color = new Color(0.4f, 0.9f, 0.4f, 1f); var fillRT = (RectTransform)fill.transform; fillRT.anchorMin = new Vector2(0, 0); fillRT.anchorMax = new Vector2(1, 1); fillRT.offsetMin = Vector2.zero; fillRT.offsetMax = Vector2.zero; var handleArea = new GameObject("Handle Slide Area", typeof(RectTransform)); handleArea.transform.SetParent(go.transform, false); var haRT = (RectTransform)handleArea.transform; haRT.anchorMin = new Vector2(0, 0); haRT.anchorMax = new Vector2(1, 1); haRT.offsetMin = Vector2.zero; haRT.offsetMax = Vector2.zero; var handle = new GameObject("Handle", typeof(RectTransform), typeof(Image)); handle.transform.SetParent(handleArea.transform, false); var handleImg = handle.GetComponent(); handleImg.color = new Color(0.8f, 1f, 0.8f, 1f); var hRT = (RectTransform)handle.transform; hRT.sizeDelta = new Vector2(16, 24); hRT.anchorMin = new Vector2(0.5f, 0.5f); hRT.anchorMax = new Vector2(0.5f, 0.5f); hRT.anchoredPosition = Vector2.zero; slider.fillRect = fill.GetComponent(); slider.handleRect = handle.GetComponent(); slider.targetGraphic = handleImg; slider.direction = Slider.Direction.LeftToRight; return go; } internal static GameObject CreateLabeledSlider(Transform parent, string label, string name, float min, float max, float value) { var group = CreateVerticalGroup(parent, name + "_Group", 4, TextAnchor.UpperLeft, new RectOffset(0, 0, 0, 0)); CreateText(group.transform, name + "_Label", label, 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal); CreateSlider(group.transform, name, min, max, value); return group; } internal static GameObject CreateToggle(Transform parent, string name, string labelText, bool initial) { var go = new GameObject(name, typeof(RectTransform), typeof(Toggle)); go.transform.SetParent(parent, false); var bg = CreateImage(go.transform, "Background", new Color(0.2f, 0.2f, 0.2f)); var check = CreateImage(bg.transform, "Checkmark", new Color(0.7f, 1f, 0.7f)); var label = CreateText(go.transform, "Label", labelText, 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal); var toggle = go.GetComponent(); toggle.isOn = initial; toggle.graphic = check.GetComponent(); toggle.targetGraphic = bg.GetComponent(); var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 40); var bgRT = (RectTransform)bg.transform; bgRT.anchorMin = new Vector2(0, 0.5f); bgRT.anchorMax = new Vector2(0, 0.5f); bgRT.pivot = new Vector2(0, 0.5f); bgRT.sizeDelta = new Vector2(24, 24); var checkRT = (RectTransform)check.transform; checkRT.anchorMin = checkRT.anchorMax = new Vector2(0.5f, 0.5f); checkRT.sizeDelta = new Vector2(16, 16); var labelRT = (RectTransform)label.transform; labelRT.anchorMin = new Vector2(0, 0); labelRT.anchorMax = new Vector2(1, 1); labelRT.offsetMin = new Vector2(34, 0); labelRT.offsetMax = new Vector2(0, 0); return go; } internal static GameObject CreateImage(Transform parent, string name, Color color) { var go = new GameObject(name, typeof(RectTransform), typeof(Image)); go.transform.SetParent(parent, false); var img = go.GetComponent(); img.color = color; return go; } internal static void CreateSpacer(Transform parent, float height) { var spacer = new GameObject("Spacer", typeof(RectTransform)); spacer.transform.SetParent(parent, false); var rt = (RectTransform)spacer.transform; rt.sizeDelta = new Vector2(0, height); } internal static ScrollRect CreateScrollList(Transform parent, out Transform content, string scrollName, string viewportName, string contentName) { var scrollGO = new GameObject(scrollName, typeof(RectTransform), typeof(Image), typeof(ScrollRect)); scrollGO.transform.SetParent(parent, false); var srt = (RectTransform)scrollGO.transform; srt.sizeDelta = new Vector2(0, 240); var img = scrollGO.GetComponent(); img.color = new Color(0, 0, 0, 0.3f); var viewport = new GameObject(viewportName, typeof(RectTransform), typeof(Mask), typeof(Image)); viewport.transform.SetParent(scrollGO.transform, false); var vImg = viewport.GetComponent(); vImg.color = new Color(0, 0, 0, 0.1f); viewport.GetComponent().showMaskGraphic = false; var vprt = (RectTransform)viewport.transform; vprt.anchorMin = new Vector2(0, 0); vprt.anchorMax = new Vector2(1, 1); vprt.offsetMin = Vector2.zero; vprt.offsetMax = Vector2.zero; var contentGO = new GameObject(contentName, typeof(RectTransform), typeof(VerticalLayoutGroup)); contentGO.transform.SetParent(viewport.transform, false); var vlg = contentGO.GetComponent(); vlg.spacing = 8; vlg.childAlignment = TextAnchor.UpperLeft; vlg.childForceExpandWidth = true; var crt = (RectTransform)contentGO.transform; crt.anchorMin = new Vector2(0, 1); crt.anchorMax = new Vector2(1, 1); crt.pivot = new Vector2(0.5f, 1); crt.offsetMin = Vector2.zero; crt.offsetMax = Vector2.zero; var csf = contentGO.AddComponent(); csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize; content = contentGO.transform; var scroll = scrollGO.GetComponent(); scroll.viewport = (RectTransform)viewport.transform; scroll.content = (RectTransform)content; scroll.horizontal = false; scroll.vertical = true; return scroll; } } } #endif