feat: Implement DownDash ability and related systems

- Added DownDash ability with cooldown and speed configuration.
- Introduced DownDashState to handle down dashing mechanics, including gravity manipulation and animation playback.
- Updated PlayerMovement to support DownDash functionality.
- Enhanced PlayerStats to manage spring charge consumption and healing.
- Modified PlayerCombat and WeaponHitBoxInstance to support new hit confirmation events.
- Updated AbilityType to include new form types for character abilities.
- Improved Gizmos for better visualization of enemy detection and attack ranges.
- Added feedback systems for form switching in PlayerFeedback and IFeedbackPlayer.
- Refactored combat and movement states to accommodate new abilities and ensure smooth transitions.
This commit is contained in:
2026-05-22 00:09:50 +08:00
parent 534de11e5d
commit 47bdc67cdf
27 changed files with 443 additions and 129 deletions

View File

@@ -3,6 +3,7 @@ using UnityEngine;
using BaseGames.Core;
using BaseGames.Core.Save;
using BaseGames.Core.Events;
using BaseGames.Feedback;
using BaseGames.Input;
namespace BaseGames.Player
@@ -21,6 +22,9 @@ namespace BaseGames.Player
[SerializeField] private FormConfigSO _config;
[SerializeField] private InputReaderSO _input;
[Header("依赖")]
[SerializeField] private PlayerStats _stats;
[Header("事件频道")]
[SerializeField] private IntEventChannelSO _onFormChanged; // 广播当前形态索引UI/Save
[SerializeField] private VoidEventChannelSO _onSkillSetChanged; // 通知 SkillHUD 刷新
@@ -29,12 +33,21 @@ namespace BaseGames.Player
public FormSO CurrentForm { get; private set; }
public FormSO[] AllForms => _config.forms;
/// <summary>当前切换 CD 剩余时间0 表示可切换。</summary>
public float SwitchCooldownRemaining => _switchCooldownTimer;
/// <summary>C# 事件WeaponManager 在 OnEnable 自订阅(架构 05 §6。</summary>
public event Action OnFormChanged;
private float _switchCooldownTimer;
private IFeedbackPlayer _feedback;
private void Awake()
{
Debug.Assert(_config != null, "[FormController] _config 未赋值,请在 Inspector 中指定 FormConfigSO。", this);
if (_stats == null)
_stats = GetComponent<PlayerStats>();
_feedback = GetComponentInChildren<IFeedbackPlayer>() ?? NullFeedbackPlayer.Instance;
}
private void OnEnable()
@@ -61,16 +74,43 @@ namespace BaseGames.Player
CurrentForm = _config.forms[0];
}
private void Update()
{
if (_switchCooldownTimer > 0f)
_switchCooldownTimer -= Time.deltaTime;
}
// ── 公共 API ────────────────────────────────────────────────────────────
/// <summary>切换到指定形态类型。若已在目标形态则不操作。</summary>
/// <summary>切换到指定形态类型。若已在目标形态、尚未解锁或 CD 未结束则不操作。</summary>
public void SwitchForm(FormType newFormType)
{
// CD 检查
if (_switchCooldownTimer > 0f) return;
// 检查对应形态的解锁标志
AbilityType required = newFormType switch
{
FormType.TianHun => AbilityType.FormTianHun,
FormType.DiHun => AbilityType.FormDiHun,
FormType.MingHun => AbilityType.FormMingHun,
_ => AbilityType.None,
};
if (required != AbilityType.None && _stats != null && !_stats.HasAbility(required))
return;
FormSO newForm = _config.GetFormByType(newFormType);
if (newForm == null || newForm == CurrentForm) return;
CurrentForm = newForm;
// 启动切换 CD
if (_config.SwitchCooldown > 0f)
_switchCooldownTimer = _config.SwitchCooldown;
// 播放对应形态切换反馈
_feedback.PlayFormSwitch((int)newFormType);
// 1. SO 事件广播索引UI/Save
_onFormChanged?.Raise(_config.GetFormIndex(newForm));