多轮审查和修复
This commit is contained in:
109
Assets/Scripts/Spells/SpellManager.cs
Normal file
109
Assets/Scripts/Spells/SpellManager.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using UnityEngine;
|
||||
using BaseGames.Player;
|
||||
using BaseGames.Input;
|
||||
|
||||
namespace BaseGames.Spells
|
||||
{
|
||||
/// <summary>
|
||||
/// 法术管理器(架构 BaseGames.Spells)。
|
||||
/// 挂在 Player 上,管理已装备法术的施放、冷却与资源消耗。
|
||||
/// 装备/卸下法术通过 EquipSpell / UnequipSpell 公共 API 完成(如护符系统调用)。
|
||||
///
|
||||
/// 输入事件:订阅 InputReaderSO.SpellCastEvent(对应 InputActionAsset 中的 "Spell" Action)。
|
||||
/// </summary>
|
||||
public class SpellManager : MonoBehaviour
|
||||
{
|
||||
[Header("依赖引用")]
|
||||
[SerializeField] private PlayerStats _stats;
|
||||
[SerializeField] private InputReaderSO _input;
|
||||
|
||||
[Header("法术挂载点")]
|
||||
[Tooltip("法术 HitBox / 投射物的生成位置")]
|
||||
[SerializeField] private Transform _spellSocket;
|
||||
|
||||
// 当前装备的法术(单槽;如需多槽可扩展为数组)
|
||||
private SpellSO _equippedSpell;
|
||||
private float _cooldownRemaining;
|
||||
|
||||
// ── 生命周期 ──────────────────────────────────────────────────────────
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_input != null)
|
||||
_input.SpellCastEvent += TryCastSpell;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_input != null)
|
||||
_input.SpellCastEvent -= TryCastSpell;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_cooldownRemaining > 0f)
|
||||
_cooldownRemaining -= Time.deltaTime;
|
||||
}
|
||||
|
||||
// ── 公共 API ─────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>装备一个法术(替换当前已装备的)。</summary>
|
||||
public void EquipSpell(SpellSO spell)
|
||||
{
|
||||
_equippedSpell = spell;
|
||||
_cooldownRemaining = 0f;
|
||||
}
|
||||
|
||||
/// <summary>卸下当前装备的法术。</summary>
|
||||
public void UnequipSpell()
|
||||
{
|
||||
_equippedSpell = null;
|
||||
_cooldownRemaining = 0f;
|
||||
}
|
||||
|
||||
/// <summary>返回当前冷却进度(0 = 就绪,1 = 刚施放)。供 UI 血条使用。</summary>
|
||||
public float CooldownFraction
|
||||
=> _equippedSpell != null && _equippedSpell.cooldown > 0f
|
||||
? Mathf.Clamp01(_cooldownRemaining / _equippedSpell.cooldown)
|
||||
: 0f;
|
||||
|
||||
public SpellSO EquippedSpell => _equippedSpell;
|
||||
public bool IsReady => _equippedSpell != null && _cooldownRemaining <= 0f;
|
||||
|
||||
// ── 内部施放逻辑 ──────────────────────────────────────────────────────
|
||||
|
||||
private void TryCastSpell()
|
||||
{
|
||||
if (_equippedSpell == null || _cooldownRemaining > 0f) return;
|
||||
if (_stats == null) return;
|
||||
|
||||
// 消耗资源(扣除护符提供的灵力减免后计算实际消耗)
|
||||
int cost = Mathf.Max(0, _equippedSpell.baseCost - _stats.SoulCostReduction);
|
||||
bool consumed = _equippedSpell.resourceType == SpellResourceType.SoulPower
|
||||
? _stats.ConsumeSoulPower(cost)
|
||||
: _stats.ConsumeSpiritPower(cost);
|
||||
if (!consumed) return;
|
||||
|
||||
_cooldownRemaining = _equippedSpell.cooldown;
|
||||
|
||||
ExecuteSpellEffect(_equippedSpell);
|
||||
}
|
||||
|
||||
private void ExecuteSpellEffect(SpellSO spell)
|
||||
{
|
||||
// 生成 HitBox Prefab(近战/爆炸类法术)
|
||||
if (spell.spellHitBoxPrefab != null)
|
||||
{
|
||||
var socket = _spellSocket != null ? _spellSocket : transform;
|
||||
Instantiate(spell.spellHitBoxPrefab, socket.position, socket.rotation, socket);
|
||||
}
|
||||
|
||||
// TODO: 根据 spell.effectType 扩展施放逻辑
|
||||
// SpellEffectType.Projectile → ProjectileManager 发射
|
||||
// SpellEffectType.AreaOfEffect → AreaOfEffectSpawner 生成
|
||||
// SpellEffectType.SelfBuff → PlayerStats/StatusEffectManager 施加增益
|
||||
// SpellEffectType.SummonShade → 召唤投影 Prefab
|
||||
// SpellEffectType.TeleportBlink → 瞬移至光标/方向
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user