C# 检查模型与两个不同对象之间是否同时发生碰撞

C# 检查模型与两个不同对象之间是否同时发生碰撞,c#,unity3d,events,triggers,C#,Unity3d,Events,Triggers,在VR unity项目中工作,尝试编写一些C#脚本 我的角色模型有两只脚,在虚拟现实中使用跟踪器进行控制。我需要一种方法来找出双脚何时与立方体碰撞。立方体A同时代表左脚,立方体B同时代表右脚。这样我可以在满足条件时生成另一个对象 怎么做呢?哪个对象应该有脚本?现在,立方体有一个OnTiggerStay功能,用于检查与脚的碰撞,并将立方体颜色更改为绿色 using System.Collections; using System.Collections.Generic; using UnityEn

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

我的角色模型有两只脚,在虚拟现实中使用跟踪器进行控制。我需要一种方法来找出双脚何时与立方体碰撞。立方体A同时代表左脚,立方体B同时代表右脚。这样我可以在满足条件时生成另一个对象

怎么做呢?哪个对象应该有脚本?现在,立方体有一个OnTiggerStay功能,用于检查与脚的碰撞,并将立方体颜色更改为绿色

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

public class CheckForFoot : MonoBehaviour {

    void OnTriggerStay(Collider other)
    {



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

怎么做呢

使用
Collider2D
,这将是
Physics2D.IsTouching(collider1,collider2)
,但这是Collider/3D,不同的是没有内置的API来实现这一点。这很复杂,但也有可能。以下是简化的步骤:

1。使用
KeyValuePair
List
存储触摸对象

static private List<KeyValuePair<GameObject, GameObject>> collisionList;
用法:

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

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");
    }
}
公共游戏对象foot1;
公共游戏对象2;
无效更新()
{
//检查游戏对象是否接触到脚
bool touching=碰撞检测。i触摸(foot1,foot2);
如果(触摸)
{
Log(“leg1和leg2”);
}
其他的
{
Log(“leg1和leg2不接触”);
}
}

通过使用不同的数据结构,可以大大改进公认的答案

为什么不将一个对象映射到一个HashSet,该HashSet可以在
字典中容纳您所需的任意多个对象呢

private static Dictionary<GameObject, HashSet<GameObject>> collisions =
    new Dictionary<GameObject, HashSet<GameObject>>();

private void Awake ()
{
    // Create a new entry in the Dictionary for this object
    collisions.Add(gameObject, new HashSet<GameObject>());
}

void OnTriggerEnter(Collider other)
{
    // Your Register method basically becomes that simple
    if(!collisions [gameObject].Contains(other.gameObject))
    {
        collisions[gameObject].Add(other.gameObject);
    }
}

void OnTriggerExit(Collider other)
{
    // And accordingly the unregister
    if(collisions [gameObject].Contains(other.gameObject))
    {
        collisionss[gameObject].Remove(other.gameObject);
    }
}

// Also the getter for your touches becomes way simpler
public static bool IsTouching(GameObject obj1, GameObject obj2)
{
    if(!collisions.ContainsKey(obj1)
    {
        return false;
    }

    return collisions[obj1].Contains(obj2);
}

private void OnDestroy ()
{
    // remove the entry for this object
    collisions.RemoveKey(gameObject);
}
私有静态字典冲突=
新字典();
私人空间()
{
//在字典中为此对象创建新条目
添加(gameObject,newhashset());
}
无效对撞机(对撞机其他)
{
//你的注册方法基本上就这么简单了
如果(!碰撞[gameObject].包含(其他.gameObject))
{
冲突[gameObject]。添加(其他.gameObject);
}
}
void OnTriggerExit(碰撞器其他)
{
//因此,取消注册
如果(碰撞[gameObject]。包含(其他.gameObject))
{
碰撞[gameObject]。移除(其他.gameObject);
}
}
//同时,触碰的获得者也变得更加简单
公共静态布尔值IsTouching(游戏对象obj1、游戏对象obj2)
{
如果(!collisions.ContainsKey(obj1)
{
返回false;
}
返回冲突[obj1]。包含(obj2);
}
私有void OnDestroy()
{
//删除此对象的条目
碰撞。移除键(游戏对象);
}

“同时”在游戏引擎编程中,这是一件很难确保的事情。您可能希望记录一次碰撞发生的时间,记录另一次碰撞发生的时间,并检查这两次是否在一定的公差范围内,例如200毫秒。谢谢,我将尝试在
OnTriggerEnter
中查看它。您可以添加任何c对列表进行合并,然后将它们从列表中删除。然后,每个帧根据当前碰撞的对象列表执行任何碰撞检查。这非常有帮助!我现在面临的问题是,它只检查两条腿之间的碰撞,而不应该这样做检查。他们唯一应该检查的是一只脚从一边到另一边的立方体之间的碰撞。通过修改条件使其工作
bool touch=CollisionDetection.IsTouching(hand1,cube1)和&CollisionDetection.IsTouching(hand2,cube2)
它检测两个物体是否同时接触并工作。你如何使用它取决于你想如何使用它。你正在做什么,但它应该工作。
private static Dictionary<GameObject, HashSet<GameObject>> collisions =
    new Dictionary<GameObject, HashSet<GameObject>>();

private void Awake ()
{
    // Create a new entry in the Dictionary for this object
    collisions.Add(gameObject, new HashSet<GameObject>());
}

void OnTriggerEnter(Collider other)
{
    // Your Register method basically becomes that simple
    if(!collisions [gameObject].Contains(other.gameObject))
    {
        collisions[gameObject].Add(other.gameObject);
    }
}

void OnTriggerExit(Collider other)
{
    // And accordingly the unregister
    if(collisions [gameObject].Contains(other.gameObject))
    {
        collisionss[gameObject].Remove(other.gameObject);
    }
}

// Also the getter for your touches becomes way simpler
public static bool IsTouching(GameObject obj1, GameObject obj2)
{
    if(!collisions.ContainsKey(obj1)
    {
        return false;
    }

    return collisions[obj1].Contains(obj2);
}

private void OnDestroy ()
{
    // remove the entry for this object
    collisions.RemoveKey(gameObject);
}