Merge branch 'agents/wall-jump-logic-optimization'
# Conflicts: # Assets/_Game/Scripts/Player/PlayerMovement.cs # Assets/_Game/Scripts/Player/States/IdleState.cs # Assets/_Game/Scripts/Player/States/RunState.cs # Assets/_Game/Scripts/Player/States/WallJumpState.cs # Assets/_Game/Scripts/Player/States/WallSlideState.cs
This commit is contained in:
@@ -76,6 +76,20 @@ namespace BaseGames.Player.States
|
||||
return;
|
||||
}
|
||||
|
||||
// ── 抓墙:贴墙 + 朝向墙壁按键,或蹬墙跳后的自动抓墙──────────────
|
||||
var wd = Owner.WallDetector;
|
||||
if (wd != null && wd.IsTouchingWall)
|
||||
{
|
||||
int wallDir = wd.WallDirection;
|
||||
bool pressingTowardWall = Mathf.Abs(Input.MoveInput.x) > 0.01f
|
||||
&& (int)Mathf.Sign(Input.MoveInput.x) == wallDir;
|
||||
if (pressingTowardWall || Owner.IsPostWallJump)
|
||||
{
|
||||
_owner.TransitionTo(_owner.GetState<WallSlideState>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void OnStateFixedUpdate()
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace BaseGames.Player.States
|
||||
if (AnimCfg?.Idle != null)
|
||||
Anim.Play(AnimCfg.Idle);
|
||||
Move?.ZeroHorizontalVelocity();
|
||||
// 落地时重置空中能力计数器
|
||||
// 落地时重置空中能力计数器及抓墙记录
|
||||
Owner.ResetAirJumps();
|
||||
Owner.GetState<DashState>()?.ResetAirDash();
|
||||
Owner.GetState<WallSlideState>()?.ResetWallGrab();
|
||||
Owner.SetPostWallJump(false);
|
||||
}
|
||||
|
||||
public override void OnStateUpdate()
|
||||
|
||||
@@ -85,6 +85,20 @@ namespace BaseGames.Player.States
|
||||
_owner.TransitionTo(_owner.GetState<AirAttackState>());
|
||||
return;
|
||||
}
|
||||
|
||||
// ── 抓墙:贴墙 + 朝向墙壁按键,或蹬墙跳后的自动抓墙──────────────
|
||||
var wd = Owner.WallDetector;
|
||||
if (wd != null && wd.IsTouchingWall && !Move.IsGrounded)
|
||||
{
|
||||
int wallDir = wd.WallDirection;
|
||||
bool pressingTowardWall = Mathf.Abs(Input.MoveInput.x) > 0.01f
|
||||
&& (int)Mathf.Sign(Input.MoveInput.x) == wallDir;
|
||||
if (pressingTowardWall || Owner.IsPostWallJump)
|
||||
{
|
||||
_owner.TransitionTo(_owner.GetState<WallSlideState>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnStateFixedUpdate()
|
||||
|
||||
@@ -153,6 +153,47 @@ namespace BaseGames.Player.States
|
||||
? (_movementConfig != null ? _movementConfig.MaxAirJumps : 1)
|
||||
: 0;
|
||||
|
||||
// ── 抓墙高度记忆 API ──────────────────────────────────────────────────
|
||||
// wallGrabY:首次抓住某面墙壁时记录的 Y 坐标;用于防止单面墙无限向上爬。
|
||||
// wallGrabDir:当前记录所属墙壁方向(+1=右墙,-1=左墙,0=无)。
|
||||
// isPostWallJump:蹬墙跳后未落地标记,允许靠近墙壁时自动抓墙。
|
||||
private float _wallGrabY = float.NegativeInfinity;
|
||||
private int _wallGrabDir = 0;
|
||||
private bool _isPostWallJump;
|
||||
|
||||
public float WallGrabY => _wallGrabY;
|
||||
public int WallGrabDir => _wallGrabDir;
|
||||
public bool IsPostWallJump => _isPostWallJump;
|
||||
|
||||
/// <summary>
|
||||
/// 进入 WallSlideState 时调用。
|
||||
/// 不同墙壁(dir != _wallGrabDir)→ 重置并记录新高度;
|
||||
/// 同一面墙壁 → 保留原记录(防止攀爬重置)。
|
||||
/// </summary>
|
||||
public void RecordWallGrab(int dir, float y)
|
||||
{
|
||||
if (dir != _wallGrabDir)
|
||||
{
|
||||
_wallGrabDir = dir;
|
||||
_wallGrabY = y;
|
||||
}
|
||||
// 同一面墙:保留 _wallGrabY,不更新
|
||||
}
|
||||
|
||||
/// <summary>落地时重置抓墙记录(由 IdleState/RunState.OnStateEnter 调用)。</summary>
|
||||
public void ResetWallGrab()
|
||||
{
|
||||
_wallGrabY = float.NegativeInfinity;
|
||||
_wallGrabDir = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置蹬墙跳后自动抓墙标记。
|
||||
/// true:由 WallJumpState.OnStateEnter 设置;
|
||||
/// false:由 IdleState/RunState.OnStateEnter(落地)或 WallSlideState.OnStateEnter(已消耗)清除。
|
||||
/// </summary>
|
||||
public void SetPostWallJump(bool value) => _isPostWallJump = value;
|
||||
|
||||
// ── Overlay Layer API(供 SpringState / SoulSkill 等叠加动画使用)─────
|
||||
/// <summary>
|
||||
/// 在 Overlay Layer(Layer 1)播放动画,叠加于当前 Base Layer 动画之上。
|
||||
|
||||
@@ -11,10 +11,11 @@ namespace BaseGames.Player.States
|
||||
{
|
||||
if (AnimCfg?.Run != null)
|
||||
Anim.Play(AnimCfg.Run);
|
||||
// 落地时重置空中能力计数器(绝大多数情况被 IdleState 覆盖,但水平落地直接进入 RunState 时也需要)
|
||||
// 落地时重置空中能力计数器及抓墙记录(水平落地直接进入 RunState 时)
|
||||
Owner.ResetAirJumps();
|
||||
Owner.GetState<DashState>()?.ResetAirDash();
|
||||
Owner.GetState<WallSlideState>()?.ResetWallGrab();
|
||||
Owner.SetPostWallJump(false);
|
||||
}
|
||||
|
||||
public override void OnStateUpdate()
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace BaseGames.Player.States
|
||||
///
|
||||
/// 公共规则:
|
||||
/// 视为第一段跳(不消耗空中跳跃次数);支持可变高度(提前松键截断);
|
||||
/// 蹬墙后标记 PostWallJump,允许空中靠近墙壁时自动抓墙;
|
||||
/// 上升结束后转 FallState。
|
||||
/// </summary>
|
||||
public class WallJumpState : PlayerStateBase
|
||||
@@ -48,12 +49,17 @@ namespace BaseGames.Player.States
|
||||
|
||||
_inputLockTimer = Cfg.WallJumpInputLockDuration;
|
||||
|
||||
// 标记蹬墙跳后自动抓墙(在 FallState/JumpState 中消耗)
|
||||
Owner.SetPostWallJump(true);
|
||||
|
||||
// 蹬墙成功后立即恢复空中冲刺次数
|
||||
Owner.GetState<AerialDashState>()?.ResetAerialDashes();
|
||||
|
||||
// 播放蹬墙跳动画:背墙跳/对墙跳使用各自专属 Clip,留空时回退到 Jump 动画
|
||||
var wallJumpClip = _isAwayJump
|
||||
? (AnimCfg?.WallJumpAway ?? AnimCfg?.Jump)
|
||||
: (AnimCfg?.WallJumpToward ?? AnimCfg?.Jump);
|
||||
if (wallJumpClip != null) Anim?.Play(wallJumpClip);
|
||||
|
||||
Input.JumpCancelledEvent += OnJumpCancelled;
|
||||
}
|
||||
|
||||
@@ -64,7 +70,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>());
|
||||
|
||||
@@ -58,6 +58,9 @@ namespace BaseGames.Player.States
|
||||
if (AnimCfg?.WallSlide != null)
|
||||
Anim?.Play(AnimCfg.WallSlide);
|
||||
|
||||
// 消耗蹬墙跳后的自动抓墙标记
|
||||
Owner.SetPostWallJump(false);
|
||||
|
||||
Input.JumpStartedEvent += OnJumpPressed;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user