Compare commits

...

2 Commits

2 changed files with 36 additions and 2 deletions

View File

@@ -87,6 +87,9 @@ namespace BaseGames.Player
// SpritePixelSnapperLateUpdate +1000在插值结果基础上吸附到像素网格
// 与 CameraPixelSnapper 同格对齐,消除亚像素模糊;停止时 ≤2 帧像素追赶不可感知。
_rb.interpolation = RigidbodyInterpolation2D.Interpolate;
// 开启连续碰撞检测CCDKinematic 移动平台通过 MovePosition 将 Dynamic 角色推向墙体时,
// CCD 会沿移动路径追踪碰撞,确保角色在物理层被墙体表面拦截,而不是在离散步骤中穿透墙体。
_rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
}
private void FixedUpdate()
@@ -135,11 +138,21 @@ namespace BaseGames.Player
/// 在无输入时自然减速,保留跳出时的动量。
/// 若当前站在移动平台上,自动叠加 <c>_platformVelocity.x</c> 保持同步;
/// <c>_inputVelocityX</c> 只记录玩家输入分量,供 UpdateFacing / ApplyAirDrag 使用。
/// 当平台速度方向与已贴墙方向相同时,不叠加平台水平速度,
/// 防止速度叠加把角色推入墙体(物理接触已被 CCD 拦截,但速度覆盖会继续施力)。
/// </summary>
public void Move(float speedX)
{
_inputVelocityX = speedX;
_rb.velocity = new Vector2(speedX + _platformVelocity.x, _rb.velocity.y);
// 若平台将角色推向已贴墙一侧,忽略平台水平分量:
// 物理层CCD + 碰撞体)已阻止角色穿墙,速度层若继续施加同向力,
// 会在每帧产生累积穿透,导致角色卡入或被弹出墙体。
float platformX = _platformVelocity.x;
if ((platformX > 0f && _isWallRight) || (platformX < 0f && _isWallLeft))
platformX = 0f;
_rb.velocity = new Vector2(speedX + platformX, _rb.velocity.y);
}
/// <summary>
@@ -223,6 +236,17 @@ namespace BaseGames.Player
_rb.velocity = Vector2.zero;
}
/// <summary>
/// 仅翻转视觉朝向,不修改速度。用于蹬墙跳瞬间需要立即转向而不中断跳跃速度的场景。
/// dir+1 = 朝右,-1 = 朝左。
/// </summary>
public void FlipFacing(int dir)
{
if (dir == 0 || dir == _facingDirection) return;
_facingDirection = dir;
transform.localScale = new Vector3(dir, 1f, 1f);
}
// ── 取消窗口 ──────────────────────────────────────────────────────────
public void SetCancelWindowOpen(bool open) => _cancelWindowOpen = open;

View File

@@ -40,7 +40,11 @@ namespace BaseGames.Player.States
{
// 施加对应类型的速度
if (_isAwayJump)
{
Move?.WallJumpAway(_wallDir);
// 背墙跳:立即转向远离墙壁的方向(不清零速度)
Move?.FlipFacing(-_wallDir);
}
else
Move?.WallJumpToward(_wallDir);
@@ -76,7 +80,13 @@ namespace BaseGames.Player.States
var wd = Owner.WallDetector;
if (wd != null && wd.IsTouchingWall && !Move.IsGrounded)
{
Owner.TransitionTo(Owner.GetState<WallSlideState>());
// 传入真实墙壁方向,确保切换到对面墙时 WallSlideState 能正确刷新抓墙高度
var wss = Owner.GetState<WallSlideState>();
if (wss != null)
{
wss.PrepareEnter(wd.WallDirection);
Owner.TransitionTo(wss);
}
return;
}
}