添加“奖励 3 选 1”UI

- RewardSelectForm:其中包括 3 个可选的 RewardItem ,刷新和放弃按钮
- 应用战斗节点基地生命产生的额外事件
This commit is contained in:
SepComet
2026-03-02 21:42:27 +08:00
parent daba9cbdf9
commit 3e52a4df55
52 changed files with 4495 additions and 133 deletions
@@ -0,0 +1,53 @@
using GeometryTD.Definition;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class IconArea : MonoBehaviour
{
[SerializeField] private Image _board;
[SerializeField] private Image _icon;
private IconAreaContext _context;
public void OnInit(IconAreaContext context)
{
if (context == null)
{
Log.Error("Icon area need IconAreaContext.");
return;
}
_context = context;
SetIcon(_context.Icon);
SetRarity(_context.Rarity);
}
public void SetIcon(Sprite sprite)
{
_icon.sprite = sprite;
}
public void SetRarity(RarityType rarity)
{
_board.color = rarity switch
{
RarityType.White => Color.white,
RarityType.Green => Color.green,
RarityType.Blue => Color.blue,
RarityType.Purple => Color.magenta,
RarityType.Red => Color.red,
_ => Color.clear,
};
}
public void OnReset()
{
SetIcon(null);
SetRarity(RarityType.None);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ed74147813b96e4e95b5418f21999b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,171 @@
using System.Collections.Generic;
using GeometryTD.CustomEvent;
using TMPro;
using UnityEngine;
namespace GeometryTD.UI
{
public class RewardItem : MonoBehaviour
{
[SerializeField] private IconArea _iconArea;
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _typeText;
[SerializeField] private TMP_Text _descriptionText;
[SerializeField] private Transform _tagItemParent;
[SerializeField] private TagItem _tagItemTemplate;
private readonly List<TagItem> _runtimeTagItems = new List<TagItem>();
private RewardItemContext _context;
public void OnInit(RewardItemContext context)
{
if (context == null)
{
OnReset();
gameObject.SetActive(false);
return;
}
_context = context;
gameObject.SetActive(true);
if (_iconArea != null)
{
if (context.IconArea != null)
{
_iconArea.OnInit(context.IconArea);
}
else
{
_iconArea.OnReset();
}
}
if (_titleText != null)
{
_titleText.text = context.Title ?? string.Empty;
}
if (_typeText != null)
{
_typeText.text = context.TypeText ?? string.Empty;
}
if (_descriptionText != null)
{
_descriptionText.text = context.Description ?? string.Empty;
}
RefreshTags(context.Tags);
}
public void OnReset()
{
_context = null;
if (_iconArea != null)
{
_iconArea.OnReset();
}
if (_titleText != null)
{
_titleText.text = string.Empty;
}
if (_typeText != null)
{
_typeText.text = string.Empty;
}
if (_descriptionText != null)
{
_descriptionText.text = string.Empty;
}
ClearTags();
}
public void OnClick()
{
if (_context == null || !_context.IsSelectable)
{
return;
}
GameEntry.Event.Fire(this, RewardSelectItemSelectedEventArgs.Create(_context.Index));
}
private void RefreshTags(TagItemContext[] tagContexts)
{
ClearTags();
if (_tagItemParent == null || tagContexts == null || tagContexts.Length <= 0)
{
return;
}
TagItem template = ResolveTagTemplate();
if (template == null)
{
return;
}
for (int i = 0; i < tagContexts.Length; i++)
{
TagItemContext tagContext = tagContexts[i];
if (tagContext == null || string.IsNullOrWhiteSpace(tagContext.TagName))
{
continue;
}
TagItem tagItem = Instantiate(template, _tagItemParent);
tagItem.gameObject.SetActive(true);
tagItem.OnInit(tagContext);
_runtimeTagItems.Add(tagItem);
}
}
private TagItem ResolveTagTemplate()
{
if (_tagItemTemplate != null)
{
return _tagItemTemplate;
}
if (_tagItemParent == null)
{
return null;
}
_tagItemTemplate = _tagItemParent.GetComponentInChildren<TagItem>(true);
if (_tagItemTemplate != null)
{
_tagItemTemplate.gameObject.SetActive(false);
}
return _tagItemTemplate;
}
private void ClearTags()
{
for (int i = _runtimeTagItems.Count - 1; i >= 0; i--)
{
TagItem tagItem = _runtimeTagItems[i];
if (tagItem != null)
{
Destroy(tagItem.gameObject);
}
}
_runtimeTagItems.Clear();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 271f2a0727c521c4280eb2d47fd8de33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,167 @@
using GeometryTD.CustomEvent;
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class RewardSelectForm : UGuiForm
{
[SerializeField] private Transform _selectItemParent;
[SerializeField] private RewardItem[] _rewardItems;
[SerializeField] private TMP_Text _tipText;
[SerializeField] private TMP_Text _refreshButtonText;
[SerializeField] private CommonButton _refreshButton;
[SerializeField] private CommonButton _giveUpButton;
private RewardSelectFormContext _context;
public void OnInit(RewardSelectFormContext context)
{
if (context == null)
{
Log.Error("RewardSelectForm need Context.");
return;
}
RefreshUI(context);
}
public void RefreshUI(RewardSelectFormContext context)
{
_context = context;
EnsureRewardItems();
if (_tipText != null)
{
_tipText.text = context?.TipText ?? string.Empty;
}
if (_refreshButtonText != null)
{
_refreshButtonText.text = context?.RefreshButtonText ?? string.Empty;
}
if (_refreshButton != null)
{
_refreshButton.Interactive = context?.CanRefresh ?? false;
}
if (_giveUpButton != null)
{
_giveUpButton.Interactive = context?.CanGiveUp ?? false;
}
if (_rewardItems == null || _rewardItems.Length <= 0)
{
return;
}
for (int i = 0; i < _rewardItems.Length; i++)
{
RewardItem rewardItem = _rewardItems[i];
if (rewardItem == null)
{
continue;
}
RewardItemContext itemContext = null;
if (context?.RewardItems != null && i < context.RewardItems.Length)
{
itemContext = context.RewardItems[i];
}
rewardItem.OnInit(itemContext);
}
}
public void OnRefreshButtonClick()
{
if (_context != null && !_context.CanRefresh)
{
return;
}
GameEntry.Event.Fire(this, RewardSelectRefreshEventArgs.Create());
}
public void OnGiveUpButtonClick()
{
if (_context != null && !_context.CanGiveUp)
{
return;
}
GameEntry.Event.Fire(this, RewardSelectGiveUpEventArgs.Create());
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is RewardSelectFormContext context)
{
RefreshUI(context);
return;
}
Log.Warning("RewardSelectForm requires RewardSelectFormContext as userData.");
}
protected override void OnClose(bool isShutdown, object userData)
{
_context = null;
if (_tipText != null)
{
_tipText.text = string.Empty;
}
if (_refreshButtonText != null)
{
_refreshButtonText.text = string.Empty;
}
if (_rewardItems != null)
{
for (int i = 0; i < _rewardItems.Length; i++)
{
RewardItem rewardItem = _rewardItems[i];
if (rewardItem == null)
{
continue;
}
rewardItem.OnReset();
rewardItem.gameObject.SetActive(false);
}
}
base.OnClose(isShutdown, userData);
}
private void EnsureRewardItems()
{
if (_rewardItems != null && _rewardItems.Length > 0)
{
return;
}
if (_selectItemParent != null)
{
_rewardItems = _selectItemParent.GetComponentsInChildren<RewardItem>(true);
}
if (_rewardItems == null || _rewardItems.Length <= 0)
{
_rewardItems = GetComponentsInChildren<RewardItem>(true);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60b499ea8a70a7f489bbd5bf0cec5768
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
using TMPro;
using UnityEngine;
namespace GeometryTD.UI
{
public class TagItem : MonoBehaviour
{
[SerializeField] private RectTransform _bgRect;
[SerializeField] private TMP_Text _tagName;
[SerializeField] private float _bgExtraWidth = 12f;
private TagItemContext _context;
public void OnInit(TagItemContext context)
{
_context = context;
_tagName.text = _context?.TagName ?? string.Empty;
_tagName.ForceMeshUpdate();
var targetWidth = _tagName.preferredWidth + _bgExtraWidth;
_bgRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, targetWidth);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0beb75e5722a1db47af08437f98a0e63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: