多轮审查和修复
This commit is contained in:
@@ -4,7 +4,7 @@ namespace BaseGames.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家物理移动组件。封装 Rigidbody2D 操作,提供跑动、跳跃、击退等接口。
|
||||
/// Phase 2 功能(冲刺、单向平台)在此留存桩方法。
|
||||
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public class PlayerMovement : MonoBehaviour
|
||||
@@ -17,6 +17,9 @@ namespace BaseGames.Player
|
||||
[SerializeField] private Vector2 _groundCheckSize = new Vector2(0.8f, 0.05f);
|
||||
[SerializeField] private LayerMask _groundLayer;
|
||||
|
||||
[Header("朝向")]
|
||||
[SerializeField] private SpriteRenderer _spriteRenderer;
|
||||
|
||||
// ── 运行时状态 ────────────────────────────────────────────────────────
|
||||
private Rigidbody2D _rb;
|
||||
private float _coyoteTimer;
|
||||
@@ -27,6 +30,7 @@ namespace BaseGames.Player
|
||||
private int _facingDirection = 1;
|
||||
private bool _cancelWindowOpen;
|
||||
private SurfaceType _currentSurface = SurfaceType.Ground;
|
||||
private readonly Collider2D[] _groundBuffer = new Collider2D[4];
|
||||
|
||||
public bool IsGrounded => _isGrounded;
|
||||
public bool HasCoyoteTime => _coyoteTimer > 0f;
|
||||
@@ -37,8 +41,16 @@ namespace BaseGames.Player
|
||||
public Rigidbody2D Rb => _rb;
|
||||
public bool CancelWindowOpen => _cancelWindowOpen;
|
||||
public SurfaceType CurrentSurface => _currentSurface;
|
||||
/// <summary>垂直速度大于零(处于上升弧段)。供 WallJumpState 判断起跳是否结束。</summary>
|
||||
public bool IsRising => _rb.velocity.y > 0f;
|
||||
|
||||
private void Awake() => _rb = GetComponent<Rigidbody2D>();
|
||||
private void Awake()
|
||||
{
|
||||
Debug.Assert(_config != null, "[PlayerMovement] _config 未赋值,请在 Inspector 中指定 PlayerMovementConfigSO。", this);
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
if (_spriteRenderer == null)
|
||||
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
@@ -46,7 +58,7 @@ namespace BaseGames.Player
|
||||
CheckWalls();
|
||||
|
||||
if (_isGrounded)
|
||||
_coyoteTimer = _config != null ? _config.CoyoteTime : 0.12f;
|
||||
_coyoteTimer = _config.CoyoteTime;
|
||||
else
|
||||
_coyoteTimer = Mathf.Max(0f, _coyoteTimer - Time.fixedDeltaTime);
|
||||
}
|
||||
@@ -54,7 +66,6 @@ namespace BaseGames.Player
|
||||
// ── 移动 ──────────────────────────────────────────────────────────────
|
||||
public void Move(float speedX)
|
||||
{
|
||||
if (_config == null) return;
|
||||
float target = speedX;
|
||||
float current = _rb.velocity.x;
|
||||
float accel = Mathf.Abs(speedX) > 0.01f ? _config.Acceleration : _config.Deceleration;
|
||||
@@ -65,8 +76,7 @@ namespace BaseGames.Player
|
||||
// ── 跳跃 ──────────────────────────────────────────────────────────────
|
||||
public void Jump(bool isVariable = true)
|
||||
{
|
||||
float force = _config != null ? _config.JumpForce : 18f;
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, force);
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, _config.JumpForce);
|
||||
_coyoteTimer = 0f;
|
||||
}
|
||||
|
||||
@@ -95,18 +105,48 @@ namespace BaseGames.Player
|
||||
int dir = vx > 0f ? 1 : -1;
|
||||
if (dir == _facingDirection) return;
|
||||
_facingDirection = dir;
|
||||
Vector3 s = transform.localScale;
|
||||
transform.localScale = new Vector3(Mathf.Abs(s.x) * dir, s.y, s.z);
|
||||
if (_spriteRenderer != null)
|
||||
_spriteRenderer.flipX = dir < 0;
|
||||
}
|
||||
|
||||
// ── 取消窗口 ──────────────────────────────────────────────────────────
|
||||
public void SetCancelWindowOpen(bool open) => _cancelWindowOpen = open;
|
||||
|
||||
// ── Phase 2 桩 ────────────────────────────────────────────────────────
|
||||
/// <summary>Phase 2 实现冲刺。</summary>
|
||||
public void Dash(Vector2 direction, float speed) { }
|
||||
// ── 冲刺 ──────────────────────────────────────────────────────────────
|
||||
/// <summary>
|
||||
/// 施加冲刺速度(DashState/AerialDashState 调用)。
|
||||
/// direction 应为归一化水平向量(±1, 0)。
|
||||
/// 冲刺期间调用 SetGravityScale(0) 可关闭重力;结束后恢复默认重力。
|
||||
/// </summary>
|
||||
public void Dash(Vector2 direction, float speed)
|
||||
{
|
||||
_rb.velocity = new Vector2(direction.x * speed, 0f);
|
||||
}
|
||||
|
||||
/// <summary>Phase 2 实现单向平台穿透。</summary>
|
||||
/// <summary>
|
||||
/// 壁滑:将垂直速度限制为 -WallSlideSpeed(向下缓慢滑动)。
|
||||
/// WallSlideState.OnStateFixedUpdate 每帧调用。
|
||||
/// </summary>
|
||||
public void ApplyWallSlide()
|
||||
{
|
||||
float targetY = -_config.WallSlideSpeed;
|
||||
if (_rb.velocity.y < targetY)
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, targetY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 蹬墙跳:对墙方向施加相反水平力 + 向上力。
|
||||
/// wallDir = +1 (右墙) 或 -1 (左墙),跳跃方向与之相反。
|
||||
/// </summary>
|
||||
public void WallJump(int wallDir)
|
||||
{
|
||||
float forceX = -wallDir * _config.WallJumpForceX;
|
||||
float forceY = _config.WallJumpForceY;
|
||||
_rb.velocity = new Vector2(forceX, forceY);
|
||||
_coyoteTimer = 0f;
|
||||
}
|
||||
|
||||
/// <summary>单向平台穿透(输入下行 + 跳跃键时触发)。</summary>
|
||||
public void DropThroughPlatform() { }
|
||||
|
||||
// ── Physics 检测 ──────────────────────────────────────────────────────
|
||||
@@ -117,15 +157,14 @@ namespace BaseGames.Player
|
||||
? (Vector2)_groundCheck.position
|
||||
: (Vector2)transform.position + Vector2.down * 0.5f;
|
||||
|
||||
_isGrounded = Physics2D.OverlapBox(origin, _groundCheckSize, 0f, _groundLayer);
|
||||
_isGrounded = Physics2D.OverlapBoxNonAlloc(origin, _groundCheckSize, 0f, _groundBuffer, _groundLayer) > 0;
|
||||
|
||||
if (_isGrounded && !wasGrounded)
|
||||
_coyoteTimer = _config != null ? _config.CoyoteTime : 0.12f;
|
||||
_coyoteTimer = _config.CoyoteTime;
|
||||
}
|
||||
|
||||
private void CheckWalls()
|
||||
{
|
||||
if (_config == null) return;
|
||||
float len = _config.WallRayLength;
|
||||
float offY = _config.WallRayOffsetY;
|
||||
Vector2 pos = (Vector2)transform.position + Vector2.up * offY;
|
||||
|
||||
Reference in New Issue
Block a user