UI系统优化

This commit is contained in:
2026-05-25 11:54:37 +08:00
parent c7057db27d
commit 3c812cfb41
130 changed files with 4738 additions and 477 deletions

View File

@@ -14,7 +14,8 @@
"BaseGames.Combat",
"BaseGames.Feedback",
"BaseGames.Skills",
"Kybernetik.Animancer"
"Kybernetik.Animancer",
"BaseGames.Localization"
],
"autoReferenced": true,
"overrideReferences": false,

View File

@@ -0,0 +1,26 @@
using System;
namespace BaseGames.Spells
{
/// <summary>
/// 法术管理服务接口。UI 层SpellSlotWidget通过此接口读取法术状态
/// 与 SpellManager 具体实现解耦,支持测试场景下的 Mock 替换。
/// </summary>
public interface ISpellService
{
/// <summary>当前装备的法术null 表示未装备。</summary>
SpellSO EquippedSpell { get; }
/// <summary>冷却进度0 = 就绪1 = 刚施放)。</summary>
float CooldownFraction { get; }
/// <summary>法术当前是否可施放(已装备且冷却完毕)。</summary>
bool IsReady { get; }
/// <summary>
/// 法术装备或卸下时触发。参数为新法术null 表示已卸下。
/// UI 订阅此事件可实现零延迟的图标刷新,无需轮询。
/// </summary>
event Action<SpellSO> OnSpellChanged;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bad07198c62f8774da0868bceb1ccd34
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +1,9 @@
using System;
using UnityEngine;
using BaseGames.Player;
using BaseGames.Input;
using BaseGames.Feedback;
using BaseGames.Core;
namespace BaseGames.Spells
{
@@ -12,7 +14,7 @@ namespace BaseGames.Spells
///
/// 输入事件:订阅 InputReaderSO.SpellCastEvent对应 InputActionAsset 中的 "Spell" Action
/// </summary>
public class SpellManager : MonoBehaviour
public class SpellManager : MonoBehaviour, ISpellService
{
[Header("依赖引用")]
[SerializeField] private PlayerStats _stats;
@@ -27,6 +29,10 @@ namespace BaseGames.Spells
private float _cooldownRemaining;
private IFeedbackPlayer _feedback;
// ── ISpellService 事件 ────────────────────────────────────────────────
/// <inheritdoc/>
public event Action<SpellSO> OnSpellChanged;
// ── 生命周期 ──────────────────────────────────────────────────────────
private void Awake()
@@ -38,12 +44,14 @@ namespace BaseGames.Spells
private void OnEnable()
{
ServiceLocator.Register<ISpellService>(this);
if (_input != null)
_input.SpellCastEvent += TryCastSpell;
}
private void OnDisable()
{
ServiceLocator.Unregister<ISpellService>(this);
if (_input != null)
_input.SpellCastEvent -= TryCastSpell;
}
@@ -61,6 +69,7 @@ namespace BaseGames.Spells
{
_equippedSpell = spell;
_cooldownRemaining = 0f;
OnSpellChanged?.Invoke(spell);
}
/// <summary>卸下当前装备的法术。</summary>
@@ -68,6 +77,7 @@ namespace BaseGames.Spells
{
_equippedSpell = null;
_cooldownRemaining = 0f;
OnSpellChanged?.Invoke(null);
}
/// <summary>返回当前冷却进度0 = 就绪1 = 刚施放)。供 UI 血条使用。</summary>

View File

@@ -1,7 +1,9 @@
using System.Collections.Generic;
using UnityEngine;
using Animancer;
using BaseGames.Combat;
using BaseGames.Skills; // FeedbackPresetSO
using BaseGames.Localization;
namespace BaseGames.Spells
{
@@ -27,13 +29,14 @@ namespace BaseGames.Spells
/// 创建路径Assets/Data/Spells/SPL_{spellId}.asset
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/Spells/Spell")]
public class SpellSO : ScriptableObject
public class SpellSO : ScriptableObject, ILocalizableAsset
{
[Header("Identity")]
[Tooltip("全局唯一 ID建议使用 GameIds 域中的常量")]
public string spellId;
[Tooltip("本地化 Key从 LocalizationManager.Get(displayNameKey, \"Spells\") 获取)")]
public string displayNameKey;
[Tooltip("本地化 Key格式如 \"SPL_Fireball_Desc\"。通过 LocalizationManager.Get(descriptionKey, LocalizationTable.Spells) 获取。")]
[TextArea(1, 3)]
public string descriptionKey;
public Sprite icon;
@@ -73,5 +76,13 @@ namespace BaseGames.Spells
[Header("Feedback")]
public FeedbackPresetSO castFeedback;
public IEnumerable<LocalizationKeyRef> GetLocalizationKeys()
{
if (!string.IsNullOrEmpty(displayNameKey))
yield return new LocalizationKeyRef(displayNameKey, "Spells", nameof(displayNameKey));
if (!string.IsNullOrEmpty(descriptionKey))
yield return new LocalizationKeyRef(descriptionKey, "Spells", nameof(descriptionKey));
}
}
}