RunNode 接入游戏主流程

- NodeMapForm:节点地图
    - NodeItem:节点入口
This commit is contained in:
SepComet
2026-03-08 11:27:51 +08:00
parent c81bf97903
commit 5c6f9bf3a4
94 changed files with 6145 additions and 651 deletions
@@ -0,0 +1,121 @@
using UnityEngine;
using UnityEngine.UI;
using GeometryTD.CustomEvent;
using GeometryTD.Procedure;
namespace GeometryTD.UI
{
public class NodeItem : MonoBehaviour
{
private const string CombatIconAssetName = "Combat";
private const string EventIconAssetName = "Event";
private const string ShopIconAssetName = "Shop";
private const string BossIconAssetName = "BossCombat";
[SerializeField] private Image _icon;
[SerializeField] private Image _bg;
[SerializeField] private CommonButton _button;
[SerializeField] private Color _lockedColor = Color.gray;
[SerializeField] private Color _activeColor = Color.cyan;
[SerializeField] private Color _passedColor = Color.green;
[SerializeField] private Color _failedColor = Color.red;
[SerializeField] private Color _defaultIconColor = Color.white;
[SerializeField] private Color _lockedIconColor = Color.gray;
private NodeItemContext _context;
private string _requestedIconAssetName;
public void RefreshUI(NodeItemContext context)
{
_context = context;
if (_button != null)
{
_button.Interactive = context != null && context.CanClick;
}
Color targetColor = _lockedColor;
if (context == null)
{
targetColor = _lockedColor;
}
else if (context.IsCompleted)
{
targetColor = _passedColor;
}
else if (context.IsFailed)
{
targetColor = _failedColor;
}
else if (context.IsCurrent)
{
targetColor = _activeColor;
}
if (_bg != null)
{
_bg.color = targetColor;
}
if (_icon != null)
{
RefreshIcon(context != null ? context.NodeType : RunNodeType.None);
_icon.color = context != null && !context.IsLocked ? _defaultIconColor : _lockedIconColor;
}
}
public void OnClick()
{
if (_context == null || !_context.CanClick)
{
return;
}
GameEntry.Event.Fire(this, NodeMapNodeClickEventArgs.Create(_context.SequenceIndex));
}
private void RefreshIcon(RunNodeType nodeType)
{
if (_icon == null)
{
return;
}
string assetName = ResolveIconAssetName(nodeType);
_requestedIconAssetName = assetName;
if (string.IsNullOrWhiteSpace(assetName) || GameEntry.SpriteCache == null)
{
_icon.sprite = null;
return;
}
GameEntry.SpriteCache.GetSprite(assetName, sprite =>
{
if (_icon == null || _requestedIconAssetName != assetName)
{
return;
}
_icon.sprite = sprite;
});
}
private static string ResolveIconAssetName(RunNodeType nodeType)
{
switch (nodeType)
{
case RunNodeType.Combat:
return CombatIconAssetName;
case RunNodeType.Event:
return EventIconAssetName;
case RunNodeType.Shop:
return ShopIconAssetName;
case RunNodeType.BossCombat:
return BossIconAssetName;
default:
return null;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d370c24f0bca1cd49b1163c3765e0f4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,89 @@
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace GeometryTD.UI
{
public class NodeMapForm : UGuiForm
{
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _progressText;
[SerializeField] private TMP_Text _currentNodeText;
[SerializeField] private NodeItem[] _nodeItems;
private NodeMapFormContext _context;
public void RefreshUI(NodeMapFormContext context)
{
_context = context;
if (_titleText != null)
{
_titleText.text = context?.Title ?? string.Empty;
}
if (_progressText != null)
{
_progressText.text = context?.ProgressText ?? string.Empty;
}
if (_currentNodeText != null)
{
_currentNodeText.text = context?.CurrentNodeText ?? string.Empty;
}
if (_nodeItems == null)
{
return;
}
for (int i = 0; i < _nodeItems.Length; i++)
{
NodeItemContext itemContext =
context?.NodeItems != null && i < context.NodeItems.Length ? context.NodeItems[i] : null;
_nodeItems[i]?.RefreshUI(itemContext);
}
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is NodeMapFormContext context)
{
RefreshUI(context);
return;
}
Log.Warning("NodeMapForm requires NodeMapFormContext as userData.");
}
protected override void OnClose(bool isShutdown, object userData)
{
_context = null;
if (_titleText != null)
{
_titleText.text = string.Empty;
}
if (_progressText != null)
{
_progressText.text = string.Empty;
}
if (_currentNodeText != null)
{
_currentNodeText.text = string.Empty;
}
if (_nodeItems != null)
{
for (int i = 0; i < _nodeItems.Length; i++)
{
_nodeItems[i]?.RefreshUI(null);
}
}
base.OnClose(isShutdown, userData);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16f09225744e9ed45ba3ed24c27f9602
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: