补充相关 UI

- 事件 UI:EventForm
    - 选项:OptionItem
- 仓库 UI:RepoForm
    - 组装槽:CombineSlotItem
    - 组件列表槽:RepoItem
This commit is contained in:
SepComet
2026-02-26 23:29:32 +08:00
parent 11e4c1c1f2
commit d9c118ace3
59 changed files with 5986 additions and 1055 deletions
@@ -0,0 +1,102 @@
using GeometryTD.Definition;
using UnityEngine;
namespace GeometryTD.UI
{
public class CombineArea : MonoBehaviour
{
[SerializeField] private CombineSlotItem[] _slots;
public void OnInit(CombineAreaContext context)
{
if (_slots == null)
{
return;
}
for (int i = 0; i < _slots.Length; i++)
{
if (_slots[i] != null)
{
_slots[i].OnInit(i);
}
}
}
public void OnReset()
{
if (_slots == null)
{
return;
}
foreach (var slot in _slots)
{
if (slot != null)
{
slot.OnReset();
}
}
}
public void OnCombineClick()
{
// TODO: Combine logic.
}
public bool TryAssignItem(RepoItemContext itemContext)
{
if (itemContext == null || itemContext.ComponentSlotType == TowerCompSlotType.None)
{
return false;
}
CombineSlotItem targetSlot = FindSlot(itemContext.ComponentSlotType);
if (targetSlot == null || targetSlot.HasItem)
{
return false;
}
targetSlot.BindItem(itemContext);
return true;
}
public bool TryClearSlot(int slotIndex, out long removedItemId)
{
removedItemId = 0;
if (_slots == null || slotIndex < 0 || slotIndex >= _slots.Length)
{
return false;
}
CombineSlotItem slot = _slots[slotIndex];
if (slot == null || !slot.HasItem)
{
return false;
}
removedItemId = slot.BoundItemId;
slot.ClearSlot();
return true;
}
private CombineSlotItem FindSlot(TowerCompSlotType slotType)
{
if (_slots == null)
{
return null;
}
for (int i = 0; i < _slots.Length; i++)
{
CombineSlotItem slot = _slots[i];
if (slot != null && slot.AcceptSlotType == slotType)
{
return slot;
}
}
return null;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce74fc07cb1849b89ad101683cc63546
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,82 @@
using GeometryTD.CustomEvent;
using GeometryTD.Definition;
using TMPro;
using UnityEngine;
namespace GeometryTD.UI
{
public class CombineSlotItem : MonoBehaviour
{
[SerializeField] private TowerCompSlotType _acceptSlotType = TowerCompSlotType.None;
[SerializeField] private TMP_Text _titleText;
[SerializeField] private CommonButton _button;
private string _defaultTitle = string.Empty;
private long _boundItemId;
private int _slotIndex = -1;
public TowerCompSlotType AcceptSlotType => _acceptSlotType;
public bool HasItem => _boundItemId > 0;
public int SlotIndex => _slotIndex;
public long BoundItemId => _boundItemId;
private void Awake()
{
if (_titleText != null)
{
_defaultTitle = _titleText.text;
}
}
public void OnInit(int slotIndex)
{
_slotIndex = slotIndex;
ClearSlot();
}
public void BindItem(RepoItemContext itemContext)
{
_boundItemId = itemContext?.InstanceId ?? 0;
_button.Interactive = true;
if (_titleText != null)
{
_titleText.text = itemContext?.Title ?? string.Empty;
}
}
public void ClearSlot()
{
_boundItemId = 0;
_button.Interactive = false;
if (_titleText != null)
{
_titleText.text = _defaultTitle;
}
}
public void OnReset()
{
_slotIndex = -1;
ClearSlot();
}
public void OnClick()
{
if (_slotIndex < 0)
{
return;
}
GameEntry.Event.Fire(this, CombineSlotClickedEventArgs.Create(_slotIndex));
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b172c08f0d9b46d3b2cb108a1cc67377
timeCreated: 1772107100
@@ -0,0 +1,126 @@
using System.Collections.Generic;
using GameFramework.ObjectPool;
using GeometryTD.PoolObjectBase;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class CompArea : MonoBehaviour
{
[SerializeField] private Transform m_Content;
[SerializeField] private RepoItem m_ItemTemplate;
[SerializeField] private int m_InstancePoolCapacity = 64;
private readonly List<RepoItem> m_ActiveItems = new List<RepoItem>();
private readonly Dictionary<long, RepoItem> m_ItemMap = new Dictionary<long, RepoItem>();
private IObjectPool<RepoItemObject> m_ItemPool;
private string m_PoolName;
public void OnInit(CompAreaContext context)
{
if (context == null)
{
OnReset();
return;
}
EnsurePool();
OnReset();
if (context.Items == null || context.Items.Length == 0)
{
return;
}
for (int i = 0; i < context.Items.Length; i++)
{
RepoItem item = CreateOrSpawnItem();
if (item == null)
{
continue;
}
item.gameObject.SetActive(true);
item.OnInit(context.Items[i]);
m_ActiveItems.Add(item);
m_ItemMap[context.Items[i].InstanceId] = item;
}
}
public void OnReset()
{
for (int i = m_ActiveItems.Count - 1; i >= 0; i--)
{
RepoItem item = m_ActiveItems[i];
if (item == null)
{
continue;
}
item.OnReset();
item.gameObject.SetActive(false);
m_ItemPool?.Unspawn(item);
}
m_ActiveItems.Clear();
m_ItemMap.Clear();
}
private void OnDestroy()
{
OnReset();
m_ItemPool?.ReleaseAllUnused();
}
private void EnsurePool()
{
if (m_ItemPool != null)
{
return;
}
m_PoolName = $"RepoItemPool_{GetInstanceID()}";
m_ItemPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool<RepoItemObject>(m_PoolName, m_InstancePoolCapacity);
}
private RepoItem CreateOrSpawnItem()
{
if (m_ItemPool == null)
{
return null;
}
RepoItemObject itemObject = m_ItemPool.Spawn();
RepoItem item = itemObject != null ? (RepoItem)itemObject.Target : null;
if (item == null)
{
if (m_ItemTemplate == null)
{
Log.Warning("CompArea requires an item template.");
return null;
}
item = Instantiate(m_ItemTemplate);
m_ItemPool.Register(RepoItemObject.Create(item), true);
}
if (m_Content != null)
{
item.transform.SetParent(m_Content, false);
}
return item;
}
public void SetItemSelected(long itemId, bool isSelected)
{
if (!m_ItemMap.TryGetValue(itemId, out RepoItem item))
{
return;
}
item.SetSelected(isSelected);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f3b1aede0e52479995cf71ba52a69d63
timeCreated: 1772106310
@@ -6,26 +6,27 @@ namespace GeometryTD.UI
{
public class EventForm : UGuiForm
{
[SerializeField] private TMP_Text m_TitleText;
[SerializeField] private TMP_Text m_DescriptionText;
[SerializeField] private EventOptionItem[] m_OptionItems;
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _descriptionText;
[SerializeField] private EventOptionItem[] _optionItems;
private EventFormContext _context;
private EventFormContext m_Context;
public void RefreshUI(EventFormContext context)
{
m_Context = context;
_context = context;
if (m_TitleText != null)
if (_titleText != null)
{
m_TitleText.text = context?.Title ?? string.Empty;
_titleText.text = context?.Title ?? string.Empty;
}
if (m_DescriptionText != null)
if (_descriptionText != null)
{
m_DescriptionText.text = context?.Description ?? string.Empty;
_descriptionText.text = context?.Description ?? string.Empty;
}
for (int i = 0; i < m_OptionItems.Length; i++)
for (int i = 0; i < _optionItems.Length; i++)
{
EventOptionItemContext optionContext = null;
if (context?.OptionItems != null && i < context.OptionItems.Length)
@@ -33,9 +34,9 @@ namespace GeometryTD.UI
optionContext = context.OptionItems[i];
}
if (m_OptionItems[i] != null)
if (_optionItems[i] != null)
{
m_OptionItems[i].OnInit(optionContext);
_optionItems[i].OnInit(optionContext);
}
}
}
@@ -55,27 +56,27 @@ namespace GeometryTD.UI
protected override void OnClose(bool isShutdown, object userData)
{
m_Context = null;
_context = null;
if (m_TitleText != null)
if (_titleText != null)
{
m_TitleText.text = string.Empty;
_titleText.text = string.Empty;
}
if (m_DescriptionText != null)
if (_descriptionText != null)
{
m_DescriptionText.text = string.Empty;
_descriptionText.text = string.Empty;
}
for (int i = 0; i < m_OptionItems.Length; i++)
foreach (var item in _optionItems)
{
if (m_OptionItems[i] != null)
if (item != null)
{
m_OptionItems[i].OnReset();
item.OnReset();
}
}
base.OnClose(isShutdown, userData);
}
}
}
}
@@ -0,0 +1,67 @@
using UnityEngine;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class RepoForm : UGuiForm
{
[SerializeField] private CombineArea _combineArea;
[SerializeField] private CompArea _compArea;
public void RefreshUI(RepoFormContext context)
{
if (context == null)
{
return;
}
_combineArea?.OnInit(context.CombineAreaContext);
_compArea?.OnInit(context.CompAreaContext);
}
public bool TryAssignItemToCombineArea(RepoItemContext itemContext)
{
if (_combineArea == null)
{
return false;
}
return _combineArea.TryAssignItem(itemContext);
}
public bool TryClearCombineSlot(int slotIndex, out long removedItemId)
{
removedItemId = 0;
if (_combineArea == null)
{
return false;
}
return _combineArea.TryClearSlot(slotIndex, out removedItemId);
}
public void SetRepoItemSelected(long itemId, bool isSelected)
{
_compArea?.SetItemSelected(itemId, isSelected);
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is RepoFormContext context)
{
RefreshUI(context);
return;
}
Log.Warning("RepoForm requires RepoFormContext as userData.");
}
protected override void OnClose(bool isShutdown, object userData)
{
_combineArea?.OnReset();
_compArea?.OnReset();
base.OnClose(isShutdown, userData);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e10fdbb413c14f5eb749888590f56ff7
timeCreated: 1772106307
@@ -0,0 +1,69 @@
using GeometryTD.CustomEvent;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class RepoItem : MonoBehaviour
{
[SerializeField] private TMP_Text _titleText;
[SerializeField] private Image _highlightImage;
private static readonly Color NormalColor = new Color32(40, 40, 40, 180);
private static readonly Color SelectedColor = new Color32(255, 216, 102, 255);
private RepoItemContext _context;
public void OnInit(RepoItemContext context)
{
if (context == null)
{
OnReset();
return;
}
_context = context;
if (_titleText != null)
{
_titleText.text = context.Title ?? string.Empty;
}
SetSelected(false);
}
public void OnReset()
{
_context = null;
if (_titleText != null)
{
_titleText.text = string.Empty;
}
SetSelected(false);
}
public void SetSelected(bool isSelected)
{
if (_highlightImage == null)
{
return;
}
_highlightImage.color = isSelected ? SelectedColor : NormalColor;
}
public void OnClick()
{
if (_context == null)
{
return;
}
GameEntry.Event.Fire(this, RepoItemSelectedEventArgs.Create(_context.InstanceId));
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ba332072a148499b8f6ec886c661c00f
timeCreated: 1772106309