单向平台
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using BaseGames.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.Player
|
||||
@@ -34,7 +35,8 @@ namespace BaseGames.Player
|
||||
private int _facingDirection = 1;
|
||||
private bool _cancelWindowOpen;
|
||||
private SurfaceType _currentSurface = SurfaceType.Ground;
|
||||
private readonly Collider2D[] _groundBuffer = new Collider2D[4];
|
||||
private readonly Collider2D[] _groundBuffer = new Collider2D[4];
|
||||
private int _groundHitCount;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// ── 运行时调试(Inspector 中可见)───────────────────────────────
|
||||
@@ -43,6 +45,7 @@ namespace BaseGames.Player
|
||||
[SerializeField] private float _dbg_VelocityX;
|
||||
[SerializeField] private float _dbg_VelocityY;
|
||||
[SerializeField] private bool _dbg_IsGrounded;
|
||||
[SerializeField] private bool _dbg_OnOneWayPlatform;
|
||||
[SerializeField] private bool _dbg_HasCoyoteTime;
|
||||
[SerializeField] private bool _dbg_IsWallLeft;
|
||||
[SerializeField] private bool _dbg_IsWallRight;
|
||||
@@ -91,10 +94,11 @@ namespace BaseGames.Player
|
||||
_coyoteTimer = Mathf.Max(0f, _coyoteTimer - Time.fixedDeltaTime);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
_dbg_VelocityX = _rb.velocity.x;
|
||||
_dbg_VelocityY = _rb.velocity.y;
|
||||
_dbg_IsGrounded = _isGrounded;
|
||||
_dbg_HasCoyoteTime = _coyoteTimer > 0f;
|
||||
_dbg_VelocityX = _rb.velocity.x;
|
||||
_dbg_VelocityY = _rb.velocity.y;
|
||||
_dbg_IsGrounded = _isGrounded;
|
||||
_dbg_OnOneWayPlatform = _onOneWayPlatform;
|
||||
_dbg_HasCoyoteTime = _coyoteTimer > 0f;
|
||||
_dbg_IsWallLeft = _isWallLeft;
|
||||
_dbg_IsWallRight = _isWallRight;
|
||||
_dbg_CancelWindowOpen = _cancelWindowOpen;
|
||||
@@ -243,19 +247,54 @@ namespace BaseGames.Player
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, 0f);
|
||||
}
|
||||
|
||||
/// <summary>单向平台穿透(输入下行 + 跳跃键时触发)。</summary>
|
||||
public void DropThroughPlatform() { }
|
||||
/// <summary>
|
||||
/// 单向平台穿落(↓ + 跳跃键触发)。
|
||||
/// 找到脚下的 <see cref="IDropThrough"/> 并临时禁用其碰撞器;
|
||||
/// 同帧清除 IsGrounded / OnOneWayPlatform,状态机无需等到下一物理帧即可转换到 FallState。
|
||||
/// </summary>
|
||||
public void DropThroughPlatform()
|
||||
{
|
||||
if (!_onOneWayPlatform) return;
|
||||
|
||||
for (int i = 0; i < _groundHitCount; i++)
|
||||
{
|
||||
if (_groundBuffer[i] != null &&
|
||||
_groundBuffer[i].TryGetComponent<IDropThrough>(out var platform))
|
||||
{
|
||||
platform.TriggerDropThrough();
|
||||
// 立即清除着地状态,让状态机本帧即可切换到 FallState
|
||||
_isGrounded = false;
|
||||
_onOneWayPlatform = false;
|
||||
_coyoteTimer = 0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Physics 检测 ──────────────────────────────────────────────────────
|
||||
private void CheckGrounded()
|
||||
{
|
||||
if (_groundCheck == null) return;
|
||||
|
||||
bool wasGrounded = _isGrounded;
|
||||
_isGrounded = Physics2D.OverlapBoxNonAlloc(_groundCheck.position, _groundCheckSize, 0f, _groundBuffer, _groundLayer) > 0;
|
||||
_groundHitCount = Physics2D.OverlapBoxNonAlloc(
|
||||
_groundCheck.position, _groundCheckSize, 0f, _groundBuffer, _groundLayer);
|
||||
_isGrounded = _groundHitCount > 0;
|
||||
|
||||
if (_isGrounded && !wasGrounded)
|
||||
_coyoteTimer = _config.CoyoteTime;
|
||||
// 检测是否站在单向平台(含 IDropThrough 组件的碰撞体)
|
||||
_onOneWayPlatform = false;
|
||||
for (int i = 0; i < _groundHitCount; i++)
|
||||
{
|
||||
if (_groundBuffer[i] != null &&
|
||||
_groundBuffer[i].TryGetComponent<IDropThrough>(out _))
|
||||
{
|
||||
_onOneWayPlatform = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_currentSurface = (_isGrounded && _onOneWayPlatform)
|
||||
? SurfaceType.OneWayPlatform
|
||||
: SurfaceType.Ground;
|
||||
}
|
||||
|
||||
private void CheckWalls()
|
||||
|
||||
@@ -26,6 +26,13 @@ namespace BaseGames.Player.States
|
||||
_owner.TransitionTo(_owner.GetState<FallState>());
|
||||
return;
|
||||
}
|
||||
// 单向平台穿落:↓ + 跳跃键,优先于普通跳跃,避免误消耗跳跃缓冲
|
||||
if (Move.OnOneWayPlatform && Input.MoveInput.y < -0.5f && Buffer.ConsumeJump())
|
||||
{
|
||||
Move.DropThroughPlatform();
|
||||
_owner.TransitionTo(_owner.GetState<FallState>());
|
||||
return;
|
||||
}
|
||||
if (Buffer.ConsumeJump())
|
||||
{
|
||||
_owner.TransitionTo(_owner.GetState<JumpState>());
|
||||
|
||||
@@ -25,6 +25,13 @@ namespace BaseGames.Player.States
|
||||
_owner.TransitionTo(_owner.GetState<FallState>());
|
||||
return;
|
||||
}
|
||||
// 单向平台穿落:↓ + 跳跃键,优先于普通跳跃
|
||||
if (Move.OnOneWayPlatform && Input.MoveInput.y < -0.5f && Buffer.ConsumeJump())
|
||||
{
|
||||
Move.DropThroughPlatform();
|
||||
_owner.TransitionTo(_owner.GetState<FallState>());
|
||||
return;
|
||||
}
|
||||
if (Buffer.ConsumeJump())
|
||||
{
|
||||
_owner.TransitionTo(_owner.GetState<JumpState>());
|
||||
|
||||
Reference in New Issue
Block a user