多轮审查和修复
This commit is contained in:
70
Assets/Scripts/Player/PlayerWallDetector.cs
Normal file
70
Assets/Scripts/Player/PlayerWallDetector.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// 独立墙壁检测组件(架构 05_PlayerModule §13)。
|
||||
/// ⚠️ 不嵌入 PlayerMovement,以保持单一职责。
|
||||
/// 每侧发两根射线(Top + Bottom),两根均命中才视为接触墙壁(防卡角误判)。
|
||||
/// WallSlideState / WallJumpState 通过 PlayerController.WallDetector 访问。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(PlayerMovement))]
|
||||
public class PlayerWallDetector : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private PlayerMovementConfigSO _config;
|
||||
|
||||
[Header("墙壁 Layer(默认使用 \"Wall\" + \"Ground\")")]
|
||||
[SerializeField] private LayerMask _wallLayer;
|
||||
|
||||
/// <summary>当前是否正在触碰墙壁。</summary>
|
||||
public bool IsTouchingWall { get; private set; }
|
||||
|
||||
/// <summary>触碰到的墙壁方向:+1 = 右墙,-1 = 左墙,0 = 无墙。</summary>
|
||||
public int WallDirection { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Debug.Assert(_config != null, "[PlayerWallDetector] _config 未赋值,请在 Inspector 中指定 PlayerMovementConfigSO。", this);
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
bool rightWall = CheckSide(Vector2.right);
|
||||
bool leftWall = CheckSide(Vector2.left);
|
||||
|
||||
IsTouchingWall = rightWall || leftWall;
|
||||
WallDirection = rightWall ? 1 : (leftWall ? -1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 每侧发两根射线(TopRay + BottomRay),两根均命中才返回 true。
|
||||
/// </summary>
|
||||
private bool CheckSide(Vector2 dir)
|
||||
{
|
||||
Vector2 center = transform.position;
|
||||
float len = _config.WallRayLength;
|
||||
float oy = _config.WallRayOffsetY;
|
||||
int layer = _wallLayer != 0 ? (int)_wallLayer : LayerMask.GetMask("Wall", "Ground");
|
||||
|
||||
bool top = Physics2D.Raycast(center + Vector2.up * oy, dir, len, layer);
|
||||
bool bot = Physics2D.Raycast(center + Vector2.down * oy, dir, len, layer);
|
||||
return top && bot;
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_config == null) return;
|
||||
float len = _config.WallRayLength;
|
||||
float oy = _config.WallRayOffsetY;
|
||||
Vector2 center = transform.position;
|
||||
|
||||
Gizmos.color = IsTouchingWall ? Color.red : Color.cyan;
|
||||
// 右侧两根射线
|
||||
Gizmos.DrawRay(center + Vector2.up * oy, Vector2.right * len);
|
||||
Gizmos.DrawRay(center + Vector2.down * oy, Vector2.right * len);
|
||||
// 左侧两根射线
|
||||
Gizmos.DrawRay(center + Vector2.up * oy, Vector2.left * len);
|
||||
Gizmos.DrawRay(center + Vector2.down * oy, Vector2.left * len);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user