You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity2D中Physics2D.BoxCast碰撞检测与BoxCollider2D位置偏移问题

问题原因&解决方案

你遇到的投射位置偏移核心是Physics2D.BoxCast的参数没有匹配你实际挂载的BoxCollider2D的世界坐标属性,具体修改点如下:

  1. 投射起始点不能直接用transform.position,需要叠加BoxCollider2D的offset属性,得到碰撞盒在世界空间下的实际中心点
  2. 碰撞盒尺寸不能直接用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:36:03