Проверьте, происходит ли столкновение между моделью и двумя разными объектами одновременно - PullRequest
0 голосов
/ 18 мая 2018

Работая в проекте VR Unity, пытаясь создать сценарий на C #.

Моя модель персонажа имеет две ноги, которые управляются в VR с помощью трекеров.Мне нужен способ узнать, когда обе ноги сталкиваются с кубиками.куб A для левой ноги и куб B для правой ноги одновременно.Так что я могу порождать другой объект, когда условие выполнено.

Каков был бы способ сделать это?Какой объект должен иметь скрипт?Прямо сейчас, у кубов есть функция OnTriggerStay, которая проверяет столкновение с ногами и меняет цвет куба на зеленый.

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

public class CheckForFoot : MonoBehaviour {

    void OnTriggerStay(Collider other)
    {



    }
}

Таким образом, этот скрипт помещается в куб, который находится на полу.На кубе есть колье, как и на ноге.Когда происходит столкновение, я могу что-то сделать сейчас, но мне нужно выяснить, как проверить, сталкиваются ли два одинаковых куба одновременно

1 Ответ

0 голосов
/ 18 мая 2018

Каков был бы способ сделать это?

С Collider2D это было бы Physics2D.IsTouching(collider1, collider2), но это Collider / 3D и отличается от встроенного API не существует, чтобысделай это.Это сложно, но возможно.Вот упрощенные шаги:

1 . Используйте List из KeyValuePair для хранения соприкасающихся объектов.

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

Сделайте его переменной staticчтобы этот список был только один раз.

2 . Определите, когда есть триггер с OnTriggerEnter.

Сценарий обнаружения триггера с OnTriggerEnter функция должна быть прикреплена к каждому GameObject, который вы хотите обнаружить, когда они касаются друг друга.

3 . Получите два GameObjects, которые только что касались друг друга.

Youможно получить первый, используя this.gameObject, а второй GameObject - other.gameObject;.Переменная other происходит из аргумента Collider other в функции OnTriggerEnter.

4 . Теперь проверьте, существуют ли оба GameObject в переменной collisionList из # 1 .Если они этого не делают, добавьте их.Если они уже существуют, игнорируйте их.


5 . Как и # 2 , определите, когда есть выход триггера с помощью OnTriggerExit.Это означает, что Объекты больше не касаются.

6 . Получите два объекта GameObject, которые больше не касаются друг друга, как вы это делали в # 3 , но на этот раз в функции OnTriggerExit.

7 . Теперь проверьте, существуют ли оба GameObject в переменной collisionList из # 1 .Если они действительно удаляют их из этого списка.Если они не игнорируют его.

Какой объект должен иметь скрипт?

Прикрепите скрипт CollisionDetection к каждому GameObject, который вы хотите обнаружить с другим объектом.Также убедитесь, что IsTrigger коллайдера имеет значение enabled и что компонент Rigidbody также прикреплен к каждому GameObject.

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

}

USAGE:

Просто используйте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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...