UI系统优化
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
"BaseGames.Combat",
|
||||
"BaseGames.Feedback",
|
||||
"BaseGames.Skills",
|
||||
"Kybernetik.Animancer"
|
||||
"Kybernetik.Animancer",
|
||||
"BaseGames.Localization"
|
||||
],
|
||||
"autoReferenced": true,
|
||||
"overrideReferences": false,
|
||||
|
||||
26
Assets/_Game/Scripts/Spells/ISpellService.cs
Normal file
26
Assets/_Game/Scripts/Spells/ISpellService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Spells/ISpellService.cs.meta
Normal file
11
Assets/_Game/Scripts/Spells/ISpellService.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bad07198c62f8774da0868bceb1ccd34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user