Many changes to Invector inventory system, added WIP UI system, added implementation for max stamina, moving speed, attack speed, attack power, thorns
This commit is contained in:
315
Assets/Scripts/Editor/TrinketUIGenerator.cs
Normal file
315
Assets/Scripts/Editor/TrinketUIGenerator.cs
Normal file
@@ -0,0 +1,315 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using Invector.vItemManager;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Beyond
|
||||
{
|
||||
public class TrinketUIGenerator : MonoBehaviour
|
||||
{
|
||||
[MenuItem("Beyond/Generate Trinket UI")]
|
||||
public static void CreateTrinketUI()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1. Create Dedicated Canvas
|
||||
GameObject canvasObj = new GameObject("Trinket_UI_Canvas");
|
||||
Canvas c = canvasObj.AddComponent<Canvas>();
|
||||
c.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
c.sortingOrder = 99;
|
||||
|
||||
CanvasScaler scaler = canvasObj.AddComponent<CanvasScaler>();
|
||||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1920, 1080);
|
||||
scaler.matchWidthOrHeight = 0.5f; // Balanced scaling
|
||||
|
||||
canvasObj.AddComponent<GraphicRaycaster>();
|
||||
|
||||
// Add Controller
|
||||
TrinketUIController uiController = canvasObj.AddComponent<TrinketUIController>();
|
||||
uiController.mainCanvas = c;
|
||||
//uiController.trinketType = bItemType.Trinkets;
|
||||
|
||||
// 2. Main Panel Background
|
||||
GameObject mainPanel = CreateUIObject("Main_Panel", canvasObj.transform);
|
||||
Image panelImg = mainPanel.AddComponent<Image>();
|
||||
panelImg.color = new Color(0.05f, 0.05f, 0.05f, 0.95f);
|
||||
StretchToFill(mainPanel.GetComponent<RectTransform>());
|
||||
|
||||
// 3. Layout Container (The Parent of Left/Right)
|
||||
GameObject contentContainer = CreateUIObject("Content_Container", mainPanel.transform);
|
||||
StretchToFill(contentContainer.GetComponent<RectTransform>());
|
||||
RectTransform containerRect = contentContainer.GetComponent<RectTransform>();
|
||||
// Add margins so it doesn't touch screen edges
|
||||
containerRect.offsetMin = new Vector2(100, 100);
|
||||
containerRect.offsetMax = new Vector2(-100, -100);
|
||||
|
||||
HorizontalLayoutGroup hLayout = contentContainer.AddComponent<HorizontalLayoutGroup>();
|
||||
hLayout.childControlWidth = true;
|
||||
hLayout.childControlHeight = true;
|
||||
hLayout.childForceExpandWidth = true; // FORCE 50/50 SPLIT
|
||||
hLayout.childForceExpandHeight = true;
|
||||
hLayout.spacing = 50;
|
||||
|
||||
// =========================================================
|
||||
// LEFT SIDE: EQUIP AREA
|
||||
// =========================================================
|
||||
GameObject leftPanel = CreateUIObject("Left_EquipArea", contentContainer.transform);
|
||||
leftPanel.AddComponent<Image>().color = new Color(1, 1, 1, 0.05f);
|
||||
|
||||
bEquipArea equipArea = leftPanel.AddComponent<bEquipArea>();
|
||||
equipArea.equipSlots = new List<bEquipSlot>();
|
||||
equipArea.itemTypes = new List<bItemType>() { bItemType.Trinkets };
|
||||
|
||||
// Vertical Layout for the Left Panel itself
|
||||
VerticalLayoutGroup leftVL = leftPanel.AddComponent<VerticalLayoutGroup>();
|
||||
leftVL.padding = new RectOffset(20, 20, 20, 20);
|
||||
leftVL.spacing = 20;
|
||||
leftVL.childControlHeight = true;
|
||||
leftVL.childControlWidth = true;
|
||||
leftVL.childForceExpandHeight = false;
|
||||
|
||||
// Title
|
||||
TMP_Text titleTxt = CreateTMPObject("Equip_Title", leftPanel.transform, "Equipped Trinkets");
|
||||
titleTxt.rectTransform.sizeDelta = new Vector2(0, 60); // Fixed height for title
|
||||
|
||||
// References (Hidden Text)
|
||||
equipArea.displayNameText = CreateTextObject("EA_Name", "", leftPanel.transform);
|
||||
equipArea.displayDescriptionText = CreateTextObject("EA_Desc", "", leftPanel.transform);
|
||||
|
||||
// Slot Container (Centered)
|
||||
GameObject slotsContainer = CreateUIObject("Slots_Container", leftPanel.transform);
|
||||
// Make slots container take up remaining space but center its children
|
||||
LayoutElement slotsLE = slotsContainer.AddComponent<LayoutElement>();
|
||||
slotsLE.flexibleHeight = 1;
|
||||
|
||||
HorizontalLayoutGroup slotsLayout = slotsContainer.AddComponent<HorizontalLayoutGroup>();
|
||||
slotsLayout.childAlignment = TextAnchor.MiddleCenter;
|
||||
slotsLayout.spacing = 40;
|
||||
slotsLayout.childControlWidth = false; // Don't stretch slots
|
||||
slotsLayout.childControlHeight = false;
|
||||
|
||||
// Create 3 Equip Slots
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
GameObject slotObj = CreateUIObject($"EquipSlot_{i}", slotsContainer.transform);
|
||||
Image slotImg = slotObj.AddComponent<Image>();
|
||||
slotImg.color = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
slotObj.GetComponent<RectTransform>().sizeDelta = new Vector2(120, 120);
|
||||
|
||||
slotObj.AddComponent<CanvasGroup>();
|
||||
bEquipSlot equipSlot = slotObj.AddComponent<bEquipSlot>();
|
||||
equipSlot.itemType = new List<bItemType>() { bItemType.Trinkets };
|
||||
|
||||
GameObject iconObj = CreateUIObject("Icon", slotObj.transform);
|
||||
StretchToFill(iconObj.GetComponent<RectTransform>());
|
||||
Image iconImg = iconObj.AddComponent<Image>();
|
||||
iconImg.raycastTarget = false;
|
||||
iconImg.color = Color.clear; // Relies on bItemSlot to turn alpha back to 1
|
||||
|
||||
equipSlot.icon = iconImg;
|
||||
equipArea.equipSlots.Add(equipSlot);
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// RIGHT SIDE: ITEM WINDOW
|
||||
// =========================================================
|
||||
GameObject rightPanel = CreateUIObject("Right_ItemWindow", contentContainer.transform);
|
||||
rightPanel.AddComponent<Image>().color = new Color(1, 1, 1, 0.05f);
|
||||
|
||||
bItemWindow itemWindow = rightPanel.AddComponent<bItemWindow>();
|
||||
|
||||
// Vertical Layout for Right Panel
|
||||
VerticalLayoutGroup rightVL = rightPanel.AddComponent<VerticalLayoutGroup>();
|
||||
rightVL.padding = new RectOffset(20, 20, 20, 20);
|
||||
rightVL.spacing = 20;
|
||||
rightVL.childControlWidth = true;
|
||||
rightVL.childControlHeight = true;
|
||||
|
||||
// 1. Scroll View (Takes up flexible space)
|
||||
GameObject scrollView = CreateUIObject("Scroll_View", rightPanel.transform);
|
||||
LayoutElement svLE = scrollView.AddComponent<LayoutElement>();
|
||||
svLE.flexibleHeight = 1; // Take available space
|
||||
|
||||
ScrollRect scrollRect = scrollView.AddComponent<ScrollRect>();
|
||||
GameObject viewport = CreateUIObject("Viewport", scrollView.transform);
|
||||
StretchToFill(viewport.GetComponent<RectTransform>());
|
||||
viewport.AddComponent<Mask>();
|
||||
viewport.AddComponent<Image>().color = new Color(1,1,1,0.01f);
|
||||
|
||||
GameObject content = CreateUIObject("Content", viewport.transform);
|
||||
RectTransform contentRT = content.GetComponent<RectTransform>();
|
||||
contentRT.anchorMin = new Vector2(0, 1);
|
||||
contentRT.anchorMax = new Vector2(1, 1);
|
||||
contentRT.pivot = new Vector2(0.5f, 1);
|
||||
|
||||
GridLayoutGroup grid = content.AddComponent<GridLayoutGroup>();
|
||||
grid.cellSize = new Vector2(100, 100);
|
||||
grid.spacing = new Vector2(15, 15);
|
||||
|
||||
ContentSizeFitter csf = content.AddComponent<ContentSizeFitter>();
|
||||
csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
scrollRect.content = contentRT;
|
||||
scrollRect.viewport = viewport.GetComponent<RectTransform>();
|
||||
itemWindow.contentWindow = contentRT;
|
||||
|
||||
// 2. Details Panel (Fixed Height at bottom)
|
||||
GameObject detailsPanel = CreateUIObject("Details_Panel", rightPanel.transform);
|
||||
LayoutElement detailsLE = detailsPanel.AddComponent<LayoutElement>();
|
||||
detailsLE.minHeight = 300;
|
||||
detailsLE.preferredHeight = 300;
|
||||
|
||||
VerticalLayoutGroup detailsLayout = detailsPanel.AddComponent<VerticalLayoutGroup>();
|
||||
detailsLayout.spacing = 5;
|
||||
detailsLayout.childControlHeight = true;
|
||||
detailsLayout.childForceExpandHeight = false;
|
||||
|
||||
// Details Components (Auto-Sizing Text)
|
||||
itemWindow.displayNameText = CreateTMPObject("Name_Text", detailsPanel.transform, "Item Name");
|
||||
itemWindow.displayNameText.fontStyle = FontStyles.Bold;
|
||||
|
||||
itemWindow.displayTypeText = CreateTextObject("Type_Text", "Item Type", detailsPanel.transform);
|
||||
itemWindow.displayAttributesText = CreateTextObject("Attributes_Text", "Stats...", detailsPanel.transform);
|
||||
itemWindow.displayAmountText = CreateTextObject("Amount_Text", "", detailsPanel.transform);
|
||||
|
||||
// Description
|
||||
GameObject descContainer = CreateUIObject("Desc_Container", detailsPanel.transform);
|
||||
LayoutElement descLE = descContainer.AddComponent<LayoutElement>();
|
||||
descLE.flexibleHeight = 1; // Description expands to fill gap
|
||||
|
||||
descContainer.AddComponent<VerticalLayoutGroup>();
|
||||
itemWindow.displayDescriptionText = CreateTMPObject("Desc_Text", descContainer.transform, "Description...");
|
||||
itemWindow.displayDescriptionText.alignment = TextAlignmentOptions.TopLeft;
|
||||
itemWindow.descriptionTransform = descContainer.GetComponent<RectTransform>();
|
||||
|
||||
// Submit Button
|
||||
GameObject btnObj = CreateUIObject("Submit_Button", detailsPanel.transform);
|
||||
LayoutElement btnLE = btnObj.AddComponent<LayoutElement>();
|
||||
btnLE.minHeight = 50;
|
||||
btnLE.preferredHeight = 50;
|
||||
|
||||
btnObj.AddComponent<Image>().color = new Color(0, 0.6f, 0, 1);
|
||||
Button submitBtn = btnObj.AddComponent<Button>();
|
||||
|
||||
TMP_Text btnText = CreateTMPObject("Btn_Text", btnObj.transform, "EQUIP");
|
||||
StretchToFill(btnText.rectTransform);
|
||||
|
||||
// Serialization
|
||||
SerializedObject so = new SerializedObject(itemWindow);
|
||||
so.Update();
|
||||
|
||||
SerializedProperty propBtn = so.FindProperty("button");
|
||||
if (propBtn != null && btnObj != null) propBtn.objectReferenceValue = btnObj;
|
||||
|
||||
SerializedProperty propBtnText = so.FindProperty("submitButtonText");
|
||||
if (propBtnText != null && btnText != null) propBtnText.objectReferenceValue = btnText;
|
||||
|
||||
SerializedProperty propConsumeBtn = so.FindProperty("consumeButton");
|
||||
if (propConsumeBtn != null && btnObj != null) propConsumeBtn.objectReferenceValue = btnObj;
|
||||
|
||||
// Need to assign Image for serialization, even if we don't use it in UI layout much
|
||||
GameObject dummyImg = CreateUIObject("DummyImg", detailsPanel.transform);
|
||||
dummyImg.SetActive(false); // Hide it
|
||||
itemWindow.displayItemImage = dummyImg.AddComponent<Image>();
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
// =========================================================
|
||||
// TEMPLATE SLOT PREFAB
|
||||
// =========================================================
|
||||
GameObject slotTemplate = CreateUIObject("Slot_Template_Prefab", canvasObj.transform);
|
||||
Image templateBg = slotTemplate.AddComponent<Image>();
|
||||
templateBg.color = new Color(0.3f, 0.3f, 0.3f);
|
||||
|
||||
slotTemplate.AddComponent<CanvasGroup>();
|
||||
bItemSlot itemSlotScript = slotTemplate.AddComponent<bItemSlot>();
|
||||
|
||||
GameObject tIcon = CreateUIObject("Icon", slotTemplate.transform);
|
||||
StretchToFill(tIcon.GetComponent<RectTransform>());
|
||||
itemSlotScript.icon = tIcon.AddComponent<Image>();
|
||||
itemSlotScript.icon.raycastTarget = false;
|
||||
itemSlotScript.icon.color = Color.clear;
|
||||
|
||||
GameObject tCheck = CreateUIObject("CheckIcon", slotTemplate.transform);
|
||||
RectTransform checkRT = tCheck.GetComponent<RectTransform>();
|
||||
checkRT.anchorMin = new Vector2(1,1);
|
||||
checkRT.anchorMax = new Vector2(1,1);
|
||||
checkRT.sizeDelta = new Vector2(25,25);
|
||||
checkRT.anchoredPosition = new Vector2(-10, -10);
|
||||
itemSlotScript.checkIcon = tCheck.AddComponent<Image>();
|
||||
itemSlotScript.checkIcon.color = Color.green;
|
||||
tCheck.SetActive(false);
|
||||
|
||||
itemWindow.slotPrefab = itemSlotScript;
|
||||
slotTemplate.SetActive(false);
|
||||
|
||||
// Final Wiring
|
||||
equipArea.itemPicker = itemWindow;
|
||||
uiController.trinketEquipArea = equipArea;
|
||||
uiController.trinketItemWindow = itemWindow;
|
||||
|
||||
c.enabled = false;
|
||||
Selection.activeGameObject = canvasObj;
|
||||
Debug.Log("Trinket UI (Layout Fixed) Created Successfully.");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError("Error generating UI: " + ex.Message + "\n" + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
private static GameObject CreateUIObject(string name, Transform parent)
|
||||
{
|
||||
GameObject go = new GameObject(name);
|
||||
go.AddComponent<RectTransform>();
|
||||
if(parent != null) go.transform.SetParent(parent, false);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static TMP_Text CreateTMPObject(string name, Transform parent, string text)
|
||||
{
|
||||
GameObject go = CreateUIObject(name, parent);
|
||||
TMP_Text tmp = go.AddComponent<TextMeshProUGUI>();
|
||||
if (tmp != null)
|
||||
{
|
||||
tmp.text = text;
|
||||
tmp.alignment = TextAlignmentOptions.Center;
|
||||
tmp.color = Color.white;
|
||||
// AUTO SIZING IS KEY for fixing your issue
|
||||
tmp.enableAutoSizing = true;
|
||||
tmp.fontSizeMin = 12;
|
||||
tmp.fontSizeMax = 72;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private static Text CreateTextObject(string name, string text, Transform parent)
|
||||
{
|
||||
GameObject go = CreateUIObject(name, parent);
|
||||
Text txt = go.AddComponent<Text>();
|
||||
txt.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
if(txt.font == null) txt.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
txt.text = text;
|
||||
txt.alignment = TextAnchor.MiddleCenter;
|
||||
txt.color = Color.white;
|
||||
txt.resizeTextForBestFit = true; // Auto size for legacy text
|
||||
txt.resizeTextMinSize = 10;
|
||||
txt.resizeTextMaxSize = 60;
|
||||
return txt;
|
||||
}
|
||||
|
||||
private static void StretchToFill(RectTransform rt)
|
||||
{
|
||||
rt.anchorMin = Vector2.zero;
|
||||
rt.anchorMax = Vector2.one;
|
||||
rt.offsetMin = Vector2.zero;
|
||||
rt.offsetMax = Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Assets/Scripts/Editor/TrinketUIGenerator.cs.meta
Normal file
2
Assets/Scripts/Editor/TrinketUIGenerator.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16c0f64f2542a43e796e472d98159fc5
|
||||
Reference in New Issue
Block a user