unity碰撞检测

1.AABB

2.OBB

具有方向性、可以旋转

判定方式:两个多边形在所有轴上的投影都发生重叠,则判定为碰撞;否则,没有发生碰撞。

   public static bool IntersectBoxBox(Box box0, Box box1)
    {
        Vector3 v = box1.center - box0.center;

        //Compute A's basis
        Vector3 VAx = box0.rotation * new Vector3(1, 0, 0);
        Vector3 VAy = box0.rotation * new Vector3(0, 1, 0);
        Vector3 VAz = box0.rotation * new Vector3(0, 0, 1);

        Vector3[] VA = new Vector3[3];
        VA[0] = VAx;
        VA[1] = VAy;
        VA[2] = VAz;

        //Compute B's basis
        Vector3 VBx = box1.rotation * new Vector3(1, 0, 0);
        Vector3 VBy = box1.rotation * new Vector3(0, 1, 0);
        Vector3 VBz = box1.rotation * new Vector3(0, 0, 1);

        Vector3[] VB = new Vector3[3];
        VB[0] = VBx;
        VB[1] = VBy;
        VB[2] = VBz;

        Vector3 T = new Vector3(Vector3.Dot(v, VAx), Vector3.Dot(v, VAy), Vector3.Dot(v, VAz));

        float[,] R = new float[3, 3];
        float[,] FR = new float[3, 3];
        float ra, rb, t;

        for (int i = 0; i < 3; i++)
        {
            for (int k = 0; k < 3; k++)
            {
                R[i, k] = Vector3.Dot(VA[i], VB[k]);
                FR[i, k] = 1e-6f + Mathf.Abs(R[i, k]);
            }
        }

        // A's basis vectors
        for (int i = 0; i < 3; i++)
        {
            ra = box0.extents[i];
            rb = box1.extents[0] * FR[i, 0] + box1.extents[1] * FR[i, 1] + box1.extents[2] * FR[i, 2];
            t = Mathf.Abs(T[i]);
            if (t >= ra + rb) return false;
        }

        // B's basis vectors
        for (int k = 0; k < 3; k++)
        {
            ra = box0.extents[0] * FR[0, k] + box0.extents[1] * FR[1, k] + box0.extents[2] * FR[2, k];
            rb = box1.extents[k];
            t = Mathf.Abs(T[0] * R[0, k] + T[1] * R[1, k] + T[2] * R[2, k]);
            if (t >= ra + rb) return false;
        }

        //9 cross products

        //L = A0 x B0
        ra = box0.extents[1] * FR[2, 0] + box0.extents[2] * FR[1, 0];
        rb = box1.extents[1] * FR[0, 2] + box1.extents[2] * FR[0, 1];
        t = Mathf.Abs(T[2] * R[1, 0] - T[1] * R[2, 0]);
        if (t >= ra + rb) return false;

        //L = A0 x B1
        ra = box0.extents[1] * FR[2, 1] + box0.extents[2] * FR[1, 1];
        rb = box1.extents[0] * FR[0, 2] + box1.extents[2] * FR[0, 0];
        t = Mathf.Abs(T[2] * R[1, 1] - T[1] * R[2, 1]);
        if (t >= ra + rb) return false;

        //L = A0 x B2
        ra = box0.extents[1] * FR[2, 2] + box0.extents[2] * FR[1, 2];
        rb = box1.extents[0] * FR[0, 1] + box1.extents[1] * FR[0, 0];
        t = Mathf.Abs(T[2] * R[1, 2] - T[1] * R[2, 2]);
        if (t >= ra + rb) return false;

        //L = A1 x B0
        ra = box0.extents[0] * FR[2, 0] + box0.extents[2] * FR[0, 0];
        rb = box1.extents[1] * FR[1, 2] + box1.extents[2] * FR[1, 1];
        t = Mathf.Abs(T[0] * R[2, 0] - T[2] * R[0, 0]);
        if (t >= ra + rb) return false;

        //L = A1 x B1
        ra = box0.extents[0] * FR[2, 1] + box0.extents[2] * FR[0, 1];
        rb = box1.extents[0] * FR[1, 2] + box1.extents[2] * FR[1, 0];
        t = Mathf.Abs(T[0] * R[2, 1] - T[2] * R[0, 1]);
        if (t >= ra + rb) return false;

        //L = A1 x B2
        ra = box0.extents[0] * FR[2, 2] + box0.extents[2] * FR[0, 2];
        rb = box1.extents[0] * FR[1, 1] + box1.extents[1] * FR[1, 0];
        t = Mathf.Abs(T[0] * R[2, 2] - T[2] * R[0, 2]);
        if (t >= ra + rb) return false;

        //L = A2 x B0
        ra = box0.extents[0] * FR[1, 0] + box0.extents[1] * FR[0, 0];
        rb = box1.extents[1] * FR[2, 2] + box1.extents[2] * FR[2, 1];
        t = Mathf.Abs(T[1] * R[0, 0] - T[0] * R[1, 0]);
        if (t >= ra + rb) return false;

        //L = A2 x B1
        ra = box0.extents[0] * FR[1, 1] + box0.extents[1] * FR[0, 1];
        rb = box1.extents[0] * FR[2, 2] + box1.extents[2] * FR[2, 0];
        t = Mathf.Abs(T[1] * R[0, 1] - T[0] * R[1, 1]);
        if (t >= ra + rb) return false;

        //L = A2 x B2
        ra = box0.extents[0] * FR[1, 2] + box0.extents[1] * FR[0, 2];
        rb = box1.extents[0] * FR[2, 1] + box1.extents[1] * FR[2, 0];
        t = Mathf.Abs(T[1] * R[0, 2] - T[0] * R[1, 2]);
        if (t >= ra + rb) return false;

        return true;
    }
}

public class Box
{
    public Vector3 center;
    public Quaternion rotation;
    public Vector3 extents;
}

用法

            Box box0 = new Box
            {
                center = target.transform.position,
                rotation = target.transform.rotation,
                extents = 0.5f * (target.transform.localScale - new Vector3(0.01f, 0.01f, 0.01f))
            };
            Box box1 = new Box
            {
                center = other.transform.position,
                rotation = other.transform.rotation,
                extents = 0.5f * (other.transform.localScale - new Vector3(0.01f, 0.01f, 0.01f))
            };
            bool collision = BoxCollideDetectFilter.IntersectBoxBox(box0, box1);

参考方向包围盒(OBB)碰撞检测 - 方帅 - 博客园 (cnblogs.com)

Unity提供了多种方式进行碰撞检测。以下是一些常用的方法: 1. 物理系统:Unity的物理引擎可以自动处理物体之间的碰撞。你可以给物体添加刚体组件,并在刚体上添加碰撞器组件(如BoxCollider、SphereCollider等),然后使用物理材质来调整碰撞的行为。通过使用物理系统,你可以使用触发器(Trigger)和非触发器(Collider)来检测碰撞,并且可以处理碰撞的冲击力和反弹等效果。 2. 触发器(Trigger):你可以将一个Collider组件设置为触发器,当其他物体进入或离开该触发器时,会触发碰撞事件。你可以通过为触发器所在的脚本添加OnTriggerEnter、OnTriggerExit等函数来处理相关逻辑。 3. 非触发器(Collider):非触发器碰撞器可以用于模拟实体之间的物理交互,比如阻挡、推动等。你可以为非触发器碰撞器添加刚体组件使其具有物理属性,或者通过代码来检测碰撞事件。你可以在脚本中使用OnCollisionEnter、OnCollisionExit等函数来处理碰撞逻辑。 4. 射线检测(Raycast):射线检测是一种基于物理原理的碰撞检测方法。你可以通过从一个点发射一条射线,然后检测射线是否与其他物体相交来判断是否发生碰撞。Unity提供了Raycast函数来进行射线检测,你可以在脚本中使用该函数来处理碰撞逻辑。 以上是一些常见的碰撞检测方法,在具体场景中可以根据需求选择合适的方法来实现碰撞检测
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷积云做卷积

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值