feat: 实现抓墙高度记忆、背墙跳/对墙跳、蹬墙后自动抓墙
- PlayerController: 添加 wallGrabY/wallGrabDir/isPostWallJump 字段及 API - WallSlideState: 高度限制(超限强制下滑不可蹬跳)+ 静止悬挂 + 反向键释放 - WallJumpState: 区分背墙跳(WallJumpAwayForce)/对墙跳(WallJumpBackForce) 蹬墙后标记 PostWallJump 允许空中自动抓墙;恢复空中冲刺次数 - FallState/JumpState: 新增抓墙入口(朝向按键 OR PostWallJump 自动抓墙) - PlayerMovement.WallJump: 增加 jumpAway 参数区分两种跳跃力 - IdleState/RunState: 落地时重置抓墙记录和蹬墙跳标记 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -4,31 +4,45 @@ namespace BaseGames.Player.States
|
||||
{
|
||||
/// <summary>
|
||||
/// 蹬墙跳状态(架构 05_PlayerModule §2)。
|
||||
/// 从 WallSlideState 进入;施加背墙方向的水平 + 垂直速度;
|
||||
/// 短暂锁定水平输入后转为 FallState。
|
||||
/// 从 WallSlideState 进入;根据输入方向区分背墙跳与对墙跳;
|
||||
/// 蹬墙后标记 PostWallJump,允许空中靠近墙壁时自动抓墙(无需方向键);
|
||||
/// 输入锁结束后如贴墙则自动进入 WallSlideState;否则上升结束后转为 FallState。
|
||||
/// </summary>
|
||||
public class WallJumpState : PlayerStateBase
|
||||
{
|
||||
private float _inputLockTimer;
|
||||
private int _wallDir;
|
||||
private bool _jumpAway; // true = 背墙跳,false = 对墙跳
|
||||
|
||||
public WallJumpState(PlayerController owner) : base(owner) { }
|
||||
|
||||
public override void OnStateEnter()
|
||||
{
|
||||
// 记录墙壁方向(跳跃反向)
|
||||
// 记录墙壁方向
|
||||
_wallDir = Owner.WallDetector != null ? Owner.WallDetector.WallDirection : 0;
|
||||
if (_wallDir == 0) _wallDir = -Owner.FacingDirection;
|
||||
|
||||
// 施加蹬墙跳速度
|
||||
Move?.WallJump(_wallDir);
|
||||
// 根据输入方向判断跳跃类型:
|
||||
// 无输入或背离墙壁方向 → 背墙跳
|
||||
// 朝向墙壁方向 → 对墙跳
|
||||
float moveX = Input.MoveInput.x;
|
||||
bool pressingTowardWall = Mathf.Abs(moveX) > 0.01f
|
||||
&& (int)Mathf.Sign(moveX) == _wallDir;
|
||||
_jumpAway = !pressingTowardWall;
|
||||
|
||||
// 锁定水平输入
|
||||
// 施加蹬墙跳速度
|
||||
Move?.WallJump(_wallDir, _jumpAway);
|
||||
|
||||
// 锁定水平输入,防止立即覆盖跳跃速度
|
||||
_inputLockTimer = Cfg.WallJumpInputLockDuration;
|
||||
|
||||
// 播放跳跃动画(复用跳跃动画)
|
||||
if (AnimCfg?.Jump != null) Anim?.Play(AnimCfg.Jump);
|
||||
// 标记蹬墙跳后自动抓墙(在 FallState/WallJumpState 中消耗)
|
||||
Owner.SetPostWallJump(true);
|
||||
|
||||
// 蹬墙成功后立即恢复空中冲刺次数
|
||||
Owner.GetState<AerialDashState>()?.ResetAerialDashes();
|
||||
|
||||
if (AnimCfg?.Jump != null) Anim?.Play(AnimCfg.Jump);
|
||||
Input.JumpCancelledEvent += OnJumpCancelled;
|
||||
}
|
||||
|
||||
@@ -39,7 +53,18 @@ namespace BaseGames.Player.States
|
||||
|
||||
public override void OnStateUpdate()
|
||||
{
|
||||
// 上升结束 → 下落
|
||||
// 输入锁结束后检查是否贴墙:自动抓墙(优先于下落判断)
|
||||
if (_inputLockTimer <= 0f)
|
||||
{
|
||||
var wd = Owner.WallDetector;
|
||||
if (wd != null && wd.IsTouchingWall && !Move.IsGrounded)
|
||||
{
|
||||
Owner.TransitionTo(Owner.GetState<WallSlideState>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 上升结束 → 下落(isPostWallJump 标记保留,FallState 中继续支持自动抓墙)
|
||||
if (!Move.IsRising)
|
||||
{
|
||||
Owner.TransitionTo(Owner.GetState<FallState>());
|
||||
|
||||
Reference in New Issue
Block a user