提问者:小点点

有没有一种方法可以增加KeyValuePair使用的参数/对象的数量?


我使用下面的代码来检测多个对象的冲突。它工作得非常好,现在我需要的是一种方法,使它工作的两个以上的游戏对象,我没有任何线索,关于如何使用KeyValuePair,是别人帮我写的。我已经尝试给KeyValuePair提供两个以上的值,但没有工作。

我正在开发一种VR体验,你有不同的单词在空中漂浮,如果你把它们组合在一起,它们就会触发其他东西,比如说,如果你把它们组合在一起,你就会触发下一个lvl或类似的东西。

我想如果我能用一种动态的方式来改变游戏对象的键值,那将会非常有用。我想我需要收集两个以上的单词,但少于十个,这将完成所有短语,这将取决于短语的长度。

这些分组和检测是基于3D对撞机,其刚体标记为iStrigger。

关于如何扩展KeyValuePair值以使用更多的参数/碰撞器/游戏对象有什么线索吗?

谢啦!

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;
    }

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

public class TestCol : MonoBehaviour
{
    public GameObject Object1;
    public GameObject Object2;

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

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

共1个答案

匿名用户

不。。一对正好由两个物体组成。。。

不过,你可以让你的生活更轻松!

为什么不将一个对象映射到一个哈希集,这个哈希集可以容纳您在字典中需要的尽可能多的对象呢?>making还可以检查对象是否包含在哈希集中,比查看列表更有效。

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);
}