Unity2D中Physics2D.BoxCast碰撞检测与BoxCollider2D位置偏移问题
问题原因&解决方案
你遇到的投射位置偏移核心是Physics2D.BoxCast的参数没有匹配你实际挂载的BoxCollider2D的世界坐标属性,具体修改点如下:
- 投射起始点不能直接用
transform.position,需要叠加BoxCollider2D的offset属性,得到碰撞盒在世界空间下的实际中心点 - 碰撞盒尺寸不能直接用
boxCollider.size,这是本地坐标下的尺寸,要乘上物体的全局缩放transform.lossyScale,得到世界空间下的实际碰撞盒大小
修改后的代码如下:
using UnityEngine; public class Player : MonoBehaviour { public float speed = 2f; private BoxCollider2D boxCollider; private SpriteRenderer sprite; private Vector3 moveDelta; private RaycastHit2D hit2D; protected virtual void Awake() { boxCollider = GetComponent<BoxCollider2D>(); sprite = GetComponent<SpriteRenderer>(); } protected virtual void Update() { float x = Input.GetAxisRaw("Horizontal"); float y = Input.GetAxisRaw("Vertical"); moveDelta = new Vector3(x, y, 0) * speed; // 根据水平移动方向翻转精灵 if (moveDelta.x > 0) { sprite.flipX = false; } if (moveDelta.x < 0) { sprite.flipX = true; } // 计算碰撞盒在世界空间下的实际中心和尺寸 Vector2 colliderWorldCenter = (Vector2)transform.position + boxCollider.offset; Vector2 colliderWorldSize = Vector2.Scale(boxCollider.size, transform.lossyScale); // 手动碰撞检测 hit2D = Physics2D.BoxCast(colliderWorldCenter, colliderWorldSize, 0, new Vector2(moveDelta.x, 0), Mathf.Abs(moveDelta.x * Time.deltaTime), LayerMask.GetMask("Blocking", "Actor")); if (hit2D.collider == null) { transform.Translate(moveDelta.x * Time.deltaTime, 0, 0); } hit2D = Physics2D.BoxCast(colliderWorldCenter, colliderWorldSize, 0, new Vector2(0, moveDelta.y), Mathf.Abs(moveDelta.y * Time.deltaTime), LayerMask.GetMask("Blocking", "Actor")); if (hit2D.collider == null) { transform.Translate(0, moveDelta.y * Time.deltaTime, 0); } } }
你可以在Update中加入以下调试代码,运行时就能直观看到BoxCast使用的碰撞盒位置,和你实际挂载的碰撞盒对比确认是否对齐:
Debug.DrawWireCube(colliderWorldCenter, colliderWorldSize, Color.red, 0.1f);
内容的提问来源于stack exchange,提问作者LucidTruth
相关产品推荐
相关产品推荐

