Files
zeling_v2/Assets/Scripts/Player/States/PlayerController.cs
2026-05-08 11:04:00 +08:00

152 lines
7.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using Animancer;
using BaseGames.Core.Events;
using BaseGames.Input;
using BaseGames.Combat;
using BaseGames.Parry;
namespace BaseGames.Player.States
{
/// <summary>
/// 玩家主控制器(协调器)。位于 Player/States/ 程序集,以便引用所有具体状态类型。
/// 实现 IDamageableIsInvincible/Defense 委托 PlayerStatsTakeDamage 委托 _stats。
/// 依赖注入:所有子系统通过 [SerializeField] 字段在 Inspector 中绑定。
/// </summary>
[DefaultExecutionOrder(-100)]
[RequireComponent(typeof(InputBuffer))]
public class PlayerController : MonoBehaviour, IDamageable
{
// ── 移动 & 数值 ───────────────────────────────────────────────────────
[Header("核心组件")]
[SerializeField] private PlayerMovement _movement;
[SerializeField] private PlayerStats _stats;
[SerializeField] private AnimancerComponent _animancer;
// ── 配置 SO ───────────────────────────────────────────────────────────
[Header("配置")]
[SerializeField] private PlayerMovementConfigSO _movementConfig;
[SerializeField] private PlayerAnimationConfigSO _animConfig;
[SerializeField] private InputReaderSO _inputReader; [SerializeField] private PlayerStatsSO _statsConfig; // 数值基准HP/弹簧等初始化用)
[SerializeField] private FormConfigSO _formConfig; // Phase 2三形态切换参数
// ── 战斗组件 ──────────────────────────────────────────────────────────
[Header("战斗")]
[SerializeField] private PlayerCombat _combat;
[SerializeField] private FormController _formController;
[SerializeField] private WeaponManager _weaponManager;
[SerializeField] private SkillManager _skillManager;
[SerializeField] private SpringSystem _springSystem;
[SerializeField] private ParrySystem _parrySystem;
[SerializeField] private HurtBox _hurtBox;
[SerializeField] private ShieldComponent _shield;
// ── 事件频道 ──────────────────────────────────────────────────────────
[Header("事件频道")]
[SerializeField] private VoidEventChannelSO _onPlayerDied;
[SerializeField] private IntEventChannelSO _onHPChanged;
// ── 运行时 ────────────────────────────────────────────────────────────
private InputBuffer _inputBuffer;
// ── 状态实例 ──────────────────────────────────────────────────────────
private PlayerStateBase _currentState;
private IdleState _idleState;
private RunState _runState;
private JumpState _jumpState;
private FallState _fallState;
private AttackState _attackState;
// ── IDamageable 实现 ──────────────────────────────────────────────────
public bool IsInvincible => _stats != null && _stats.IsInvincible;
public int Defense => 0; // Phase 2从 PlayerStatsSO 读取
public void TakeDamage(DamageInfo info)
{
if (_stats == null) return;
_stats.TakeDamage(info.FinalDamage);
// Phase 2若非 DashState切换 HurtState
}
// ── 公开属性(供状态类访问)──────────────────────────────────────────
public PlayerMovement Movement => _movement;
public PlayerStats Stats => _stats;
public AnimancerComponent Animancer => _animancer;
public PlayerMovementConfigSO MovConfig => _movementConfig;
public PlayerAnimationConfigSO AnimConfig => _animConfig;
public InputReaderSO Input => _inputReader;
public InputBuffer Buffer => _inputBuffer;
public PlayerCombat Combat => _combat;
public FormController Form => _formController;
public WeaponManager Weapon => _weaponManager;
public SkillManager Skill => _skillManager;
public SpringSystem Spring => _springSystem;
public ParrySystem Parry => _parrySystem;
public HurtBox HurtBox => _hurtBox;
public ShieldComponent Shield => _shield;
public bool IsGrounded => _movement != null && _movement.IsGrounded;
public int FacingDirection => _movement != null ? _movement.FacingDirection : 1;
// ── Unity Lifecycle ───────────────────────────────────────────────────
private void Awake()
{
_inputBuffer = GetComponent<InputBuffer>();
// 注入 HurtBox 依赖Phase 1只注入护盾弹反/霸体 Phase 2
if (_hurtBox != null && _shield != null)
_hurtBox.SetShieldable(_shield);
InitializeStates();
}
private void Start()
{
TransitionTo(_idleState);
}
private void Update()
{
_currentState?.OnStateUpdate();
}
private void FixedUpdate()
{
_currentState?.OnStateFixedUpdate();
}
private void LateUpdate()
{
_movement?.UpdateFacing();
}
// ── 状态机 ────────────────────────────────────────────────────────────
public void TransitionTo(PlayerStateBase newState)
{
_currentState?.OnStateExit();
_currentState = newState;
_currentState?.OnStateEnter();
}
/// <summary>尝试切换状态(供状态内部的条件转换使用)。</summary>
public void TryTransitionState(PlayerStateBase newState)
=> TransitionTo(newState);
private void InitializeStates()
{
_idleState = new IdleState(this);
_runState = new RunState(this);
_jumpState = new JumpState(this);
_fallState = new FallState(this);
_attackState = new AttackState(this);
}
// ── 状态访问器 ────────────────────────────────────────────────────────
public IdleState IdleState => _idleState;
public RunState RunState => _runState;
public JumpState JumpState => _jumpState;
public FallState FallState => _fallState;
public AttackState AttackState => _attackState;
}
}