I'm using the following code to detect the collision of multiple objects. It is working perfectly well, now what I need is a way to make it work for more than two GameObjects, and I don't have any clue about how to use the KeyValuePair, someone else helped me to write this. I already tried to give KeyValuePair more than two values but it doesn't work.
I'm working on a VR experience where you have different words floating around and if you group them together in the air, they will trigger something else, let's say if you group them you trigger the next lvl or something like that.
I guess that it would be really useful if I could have a dynamic way of changing the KeyValuePair amount of GameObjects, I think I would need for instance to gather more than two words but less than ten, which will complete the all phrase, this will depend on how long the phrase would be.
The groups and detection are based on 3D colliders with rigidbodies marked as IsTrigger.
Any clue about how to extend the KeyValuePair values to use more arguments/colliders/GameObjects?
Thanks!
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");
}
}
}
No .. a pair consists of exactly two objects ...
I guess you took your code from this answer
You can make your life a lot easier, though!
Why not mapping one object to a HashSet which can hold as many objects you need in a
Dictionary<GameObject, HashSet<GameObject>>making also checks if an object is contained in the HashSet way more efficient than going through a list.