摄像机区域的优化
This commit is contained in:
@@ -6,6 +6,9 @@ namespace BaseGames.Player
|
||||
/// 玩家物理移动组件。封装 Rigidbody2D 操作,提供跑动、跳跃、击退等接口。
|
||||
|
||||
/// </summary>
|
||||
// 执行顺序必须早于 PlayerController(-100),确保每帧 FixedUpdate
|
||||
// 开头能在状态机写入速度之前先应用"强制清零"标记。
|
||||
[DefaultExecutionOrder(-200)]
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public class PlayerMovement : MonoBehaviour
|
||||
{
|
||||
@@ -24,6 +27,10 @@ namespace BaseGames.Player
|
||||
private Rigidbody2D _rb;
|
||||
private float _coyoteTimer;
|
||||
private bool _isGrounded;
|
||||
// Update 中调用 ZeroHorizontalVelocity 后设置此标记;
|
||||
// 下一个 FixedUpdate(-200,先于状态机 -100)读取并清零,
|
||||
// 防止状态机用旧输入把速度重新写成非零值。
|
||||
private bool _pendingHorizontalZero;
|
||||
private bool _isWallLeft;
|
||||
private bool _isWallRight;
|
||||
private bool _onOneWayPlatform;
|
||||
@@ -48,12 +55,21 @@ namespace BaseGames.Player
|
||||
{
|
||||
Debug.Assert(_config != null, "[PlayerMovement] _config 未赋值,请在 Inspector 中指定 PlayerMovementConfigSO。", this);
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
// 关闭位置插值:若开启插值,渲染位置会在速度清零后仍追赶 1~2 渲染帧,产生视觉滑行。
|
||||
_rb.interpolation = RigidbodyInterpolation2D.None;
|
||||
if (_spriteRenderer == null)
|
||||
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
// 优先处理来自 Update 的强制清零请求(在状态机 OnStateFixedUpdate 之前执行)。
|
||||
if (_pendingHorizontalZero)
|
||||
{
|
||||
_rb.velocity = new Vector2(0f, _rb.velocity.y);
|
||||
_pendingHorizontalZero = false;
|
||||
}
|
||||
|
||||
CheckGrounded();
|
||||
CheckWalls();
|
||||
|
||||
@@ -64,12 +80,25 @@ namespace BaseGames.Player
|
||||
}
|
||||
|
||||
// ── 移动 ──────────────────────────────────────────────────────────────
|
||||
/// <summary>
|
||||
/// 直接赋予目标水平速度(按键即全速,松键即停,无加速过渡)。
|
||||
/// 地面状态每帧直接到达全速;空中调用时同样即时,但配合 ApplyAirDrag
|
||||
/// 在无输入时自然减速,保留跳出时的动量。
|
||||
/// </summary>
|
||||
public void Move(float speedX)
|
||||
{
|
||||
float target = speedX;
|
||||
float current = _rb.velocity.x;
|
||||
float accel = Mathf.Abs(speedX) > 0.01f ? _config.Acceleration : _config.Deceleration;
|
||||
float newX = Mathf.MoveTowards(current, target, accel * Time.fixedDeltaTime);
|
||||
_rb.velocity = new Vector2(speedX, _rb.velocity.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 空中无输入时施加空气阻力:水平速度乘以 <paramref name="factor"/>,
|
||||
/// 低于阈值时归零,避免速度无限趋近 0。
|
||||
/// 在 FallState / JumpState / WallJumpState 的 OnStateFixedUpdate 中调用。
|
||||
/// </summary>
|
||||
public void ApplyAirDrag(float factor)
|
||||
{
|
||||
float newX = _rb.velocity.x * factor;
|
||||
if (Mathf.Abs(newX) < 0.05f) newX = 0f;
|
||||
_rb.velocity = new Vector2(newX, _rb.velocity.y);
|
||||
}
|
||||
|
||||
@@ -87,7 +116,7 @@ namespace BaseGames.Player
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 二段跳(Monarch Wings 等效)。覆盖当前垂直速度为 DoubleJumpForce。
|
||||
/// 二段跳。覆盖当前垂直速度为 DoubleJumpForce。
|
||||
/// FallState / JumpState 在检测到 HasAbility(DoubleJump) && AirJumpsLeft > 0 时调用。
|
||||
/// </summary>
|
||||
public void DoubleJump()
|
||||
@@ -105,7 +134,13 @@ namespace BaseGames.Player
|
||||
|
||||
// ── 速度控制 ──────────────────────────────────────────────────────────
|
||||
public void ZeroVelocity() => _rb.velocity = Vector2.zero;
|
||||
public void ZeroHorizontalVelocity() => _rb.velocity = new Vector2(0f, _rb.velocity.y);
|
||||
public void ZeroHorizontalVelocity()
|
||||
{
|
||||
_rb.velocity = new Vector2(0f, _rb.velocity.y);
|
||||
// 设置标记:下一个 FixedUpdate 开头再次强制清零,
|
||||
// 防止因读到旧输入而把速度重新写成非零值。
|
||||
_pendingHorizontalZero = true;
|
||||
}
|
||||
|
||||
// ── 朝向 ──────────────────────────────────────────────────────────────
|
||||
public void UpdateFacing()
|
||||
|
||||
Reference in New Issue
Block a user