检查模型和两个不同物体之间的碰撞是否同时发生 [英] Check if collision between the model and two different objects is happening at the same time

查看:31
本文介绍了检查模型和两个不同物体之间的碰撞是否同时发生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 VR unity 项目中工作,尝试编写一些 C# 脚本.

Working in a VR unity project, trying to do some C# scripting.

我的角色模型有两只脚,它们在 VR 中使用跟踪器进行控制.我需要一种方法来确定双脚何时与立方体相撞.同时左脚使用立方体A,右脚使用立方体B.这样我就可以在满足条件时生成另一个对象.

My character model has two feet that are controlled in VR using trackers. I need a way to find out when both feet are colliding with cubes. cube A for left foot and cube B for the right foot at the same time. So that I can spawn another object when the condition is met.

这样做的方法是什么?什么对象应该有脚本?现在,立方体有一个 OnTriggerStay 函数,用于检查与脚的碰撞并将立方体颜色更改为绿色.

What would be the way of doing it? What object should have the script? Right now, the cubes have a OnTriggerStay function that checks for collision with feet and changes the cube color to green.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CheckForFoot : MonoBehaviour {

    void OnTriggerStay(Collider other)
    {



    }
}

所以这个脚本被放在地板上的立方体上.立方体上有一个和脚一样的煤球.当碰撞发生时,我现在可以做一些事情,但我需要找出如何检查两个相同的立方体是否同时发生碰撞

So this script is put on the cube that is on the floor. The cube has a collier on it the same as the foot. When the collision happens I can do something now, but I need to find out how to check for two identical cubes are colliding at the same time

推荐答案

这样做的方法是什么?

What would be the way of doing it?

如果使用 Collider2D,那就是 Physics2D.IsTouching(collider1, collider2) 但这是 Collider/3D,不同的是没有内置 API 可以做到这一点.这很复杂,但可能.以下是简化的步骤:

With Collider2D, that would be Physics2D.IsTouching(collider1, collider2) but this is Collider/3D and different no built-in API exist to do this. It's complicated but possible. Here are the steps simplified:

1.使用KeyValuePairList来存储接触对象.

1.Use List of KeyValuePair to store the touching objects.

static private List<KeyValuePair<GameObject, GameObject>> collisionList;

将其设为 static 变量,以便此列表只有一次实例.

Make it a static variable so that there is only once instance of this list.

2.使用 OnTriggerEnter 检测何时有触发器.

2.Detect when there is a trigger with OnTriggerEnter.

带有 OnTriggerEnter 函数的触发器检测脚本必须附加到您要检测的每个游戏对象(当它们相互接触时).

The trigger detection script with the OnTriggerEnter function must be attached to each GameObject you want to detect when they are touching each other.

3.检索刚刚相互接触的两个游戏对象.

3.Retrieve the two GameObjects that just touched each other.

您可以使用this.gameObject 检索第一个游戏对象,使用other.gameObject; 检索第二个游戏对象.other 变量来自 OnTriggerEnter 函数中的 Collider other 参数.

You can Retrieve the first one by using this.gameObject and the second GameObject by using other.gameObject;. The other variable comes from the Collider other argument in the OnTriggerEnter function.

4.现在,检查 #1collisionList 变量中是否存在两个游戏对象.如果没有,请添加它们.如果它们已经存在,请忽略它.

4.Now, check if both GameObject exist in the collisionList variable from #1. If they don't, add them. If they already exist, ignore it.

5.就像#2一样,使用OnTriggerExit检测何时有触发退出.这意味着对象不再接触.

5.Just like #2, detect when there is a trigger exit with OnTriggerExit. This means that the Objects are no longer touching.

6. 检索不再像在 #3 中那样相互接触的两个游戏对象,但这次在 OnTriggerExit 函数中.

6.Retrieve the two GameObjects that are no longer touching each other like you did in #3 but in the OnTriggerExit function this time.

7.现在,检查 #1collisionList 变量中是否存在两个游戏对象.如果他们确实将它们从该列表中删除.如果他们不忽略它.

7.Now, check if both GameObject exist in the collisionList variable from #1. If they do remove them from that List. If they don't ignore it.

哪个对象应该有脚本?

CollisionDetection 脚本附加到您要使用另一个对象检测的每个游戏对象.还要确保对撞机的 IsTrigger 是 enabled 并且 Rigidbody 组件也附加到每个游戏对象.

Attach the CollisionDetection script to every GameObject you want to detect with another Object. Also make sure that the Collider's IsTrigger is enabled and that a Rigidbody component is attached to each GameObject too.

using System.Collections.Generic;
using UnityEngine;

public class CollisionDetection: MonoBehaviour

{
    static private List<KeyValuePair<GameObject, GameObject>> collisionList =
        new List<KeyValuePair<GameObject, GameObject>>();

    void OnTriggerEnter(Collider other)
    {
        //Debug.Log("Trigger Entered");

        //Get the two Objects involved in the collision
        GameObject col1 = this.gameObject;
        GameObject col2 = other.gameObject;

        //Add to the collison List
        RegisterTouchedItems(collisionList, col1, col2);
    }

    void OnTriggerExit(Collider other)
    {
        //Debug.Log("Trigger Exit");

        //Get the two Objects involved in the collision
        GameObject col1 = this.gameObject;
        GameObject col2 = other.gameObject;

        //Remove from the collison List
        UnRegisterTouchedItems(collisionList, col1, col2);
    }

    public static bool IsTouching(GameObject obj1, GameObject obj2)
    {
        int matchIndex = 0;
        return _itemExist(collisionList, obj1, obj2, ref matchIndex);
    }

    private void UnRegisterTouchedItems(List<KeyValuePair<GameObject, GameObject>> existingObj, GameObject col1, GameObject col2)
    {
        int matchIndex = 0;

        //Remove if it exist
        if (_itemExist(existingObj, col1, col2, ref matchIndex))

        {
            existingObj.RemoveAt(matchIndex);
        }
    }

    private void RegisterTouchedItems(List<KeyValuePair<GameObject, GameObject>> existingObj, GameObject col1, GameObject col2)
    {
        int matchIndex = 0;

        //Add if it doesn't exist
        if (!_itemExist(existingObj, col1, col2, ref matchIndex))

        {
            KeyValuePair<GameObject, GameObject> item = new KeyValuePair<GameObject, GameObject>(col1, col2);
            existingObj.Add(item);
        }
    }

    private static bool _itemExist(List<KeyValuePair<GameObject, GameObject>> existingObj, GameObject col1,
    GameObject col2, ref int matchIndex)
    {
        bool existInList = false;
        for (int i = 0; i < existingObj.Count; i++)
        {
            //Check if key and value exist and vice versa
            if ((existingObj[i].Key == col1 && existingObj[i].Value == col2) ||
                    (existingObj[i].Key == col2 && existingObj[i].Value == col1))
            {
                existInList = true;
                matchIndex = i;
                break;
            }
        }
        return existInList;
    }

}

用法:

只需使用 CollisionDetection.IsTouching(object1, object2) 来检查两个对象是否接触.

Just use CollisionDetection.IsTouching(object1, object2) to check if two Objects are touching.

public GameObject foot1;
public GameObject foot2;

void Update()
{
    //Check if feet GameObjects are touching 
    bool touching = CollisionDetection.IsTouching(foot1, foot2);

    if (touching)
    {
        Debug.Log("<color=green>leg1 and leg2 touching</color>");
    }
    else
    {
        Debug.Log("leg1 and leg2 NOT touching");
    }
}

这篇关于检查模型和两个不同物体之间的碰撞是否同时发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆