chore: initial commit
This commit is contained in:
151
Assets/Scripts/Player/States/PlayerController.cs
Normal file
151
Assets/Scripts/Player/States/PlayerController.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using UnityEngine;
|
||||
using Animancer;
|
||||
using BaseGames.Core.Events;
|
||||
using BaseGames.Input;
|
||||
using BaseGames.Combat;
|
||||
using BaseGames.Parry;
|
||||
|
||||
namespace BaseGames.Player.States
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家主控制器(协调器)。位于 Player/States/ 程序集,以便引用所有具体状态类型。
|
||||
/// 实现 IDamageable:IsInvincible/Defense 委托 PlayerStats,TakeDamage 委托 _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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user