Интерактивные объекты в Unity VR с OnOver и OnOut (C #) - PullRequest
0 голосов
/ 05 февраля 2019

Экран печати из Unity Я создаю VR-приложение в Unity для Oculus Go.Я хочу показать какой-нибудь текст поверх спрайта, пока лазерный указатель наводится на определенные игровые объекты и исчезает, когда его нет.Я пытаюсь сделать это, создавая массив, который должен показывать конкретные компоненты игровых объектов (textmesh + sprite), когда лазерный указатель наводится над этим конкретным объектом.На этом этапе отображается только последний объект text + sprite в списке, независимо от того, над каким игровым объектом находится лазерная указка.

using System;
using UnityEngine;
using VRStandardAssets.Utils;

public class ObjectManager : MonoBehaviour
{

[SerializeField] VRInteractiveItem[] InteractiveObjects;
[SerializeField] Transform reticleTransform;

private VRInteractiveItem currentObject;

void Start()
{

    foreach (VRInteractiveItem t in InteractiveObjects)
    {

        foreach (MeshRenderer renderer in t.GetComponentsInChildren<MeshRenderer>())
        {
            renderer.enabled = false;
        }


        foreach (SpriteRenderer renderer in t.GetComponentsInChildren<SpriteRenderer>())
        {
            renderer.enabled = false;
        }
    }

}


void OnEnable()
{
    foreach (VRInteractiveItem t in InteractiveObjects)
    {
        currentObject = t;
        currentObject.OnOver += Popup;
    }
}


void Popup()
{
        foreach (MeshRenderer renderer in currentObject.GetComponentsInChildren<MeshRenderer>())
        {
            renderer.enabled = true;
        }

        foreach (SpriteRenderer renderer in currentObject.GetComponentsInChildren<SpriteRenderer>())
        {
            renderer.enabled = true;
        }

        currentObject.OnOut += Popdown;
}


void Popdown()
{ 
        foreach (MeshRenderer renderer in currentObject.GetComponentsInChildren<MeshRenderer>())
        {
            renderer.enabled = false;
        }

        foreach (SpriteRenderer renderer in currentObject.GetComponentsInChildren<SpriteRenderer>())
        {
            renderer.enabled = false;
        }

}

}

Как сообщить лазерной указке, с каким конкретным игровым объектом я взаимодействую, и сделать так, чтобы он отображал только компоненты этого объекта?Я пытался найти решение с помощью идентификаторов, но не получил его для работы в VR.

1 Ответ

0 голосов
/ 05 февраля 2019

Как уже было сказано, я бы предпочел, чтобы каждый VRInteractiveItem сам обрабатывал OnOver, а не делал все это из одного компонента менеджера.


Однако вы могли бы сделать что-то (хотя яне рекомендовал бы), использует лямбда-выражения с циклом for вместо foreach в качестве обратных вызовов вместо методов, подобных

void OnEnable()
{
    for(var i= 0; i < InteractiveObjects.Length; i++)
    {
        var index = i;
        InteractiveObjects[index].OnOver += () => {
            foreach (MeshRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<MeshRenderer>())
            {
                renderer.enabled = true;
            }

            foreach (SpriteRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<SpriteRenderer>())
            {
                renderer.enabled = true;
            }

            InteractiveObjects[index].OnOut += () => {
                foreach (MeshRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<MeshRenderer>())
                {
                    renderer.enabled = false;
                }

                foreach (SpriteRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<SpriteRenderer>())
                {
                    renderer.enabled = false;
                }
            };
        };
    }
}

Проблема в том, что вы не можете удалить эти обратные вызовы (InteractiveObjects[index].OnOut -= XYZ) как вы могли бы сделать с методами.

Таким образом, вам на самом деле не следует добавлять InteractiveObjects[index].OnOut += каждый раз, когда объект наведен, потому что вы можете в конечном итоге выполнить многократное выполнение кода отключения.Вы можете скорее добавить его в OnEnable, а также

void OnEnable()
{
    for(var i= 0; i < InteractiveObjects.Length; i++)
    {
        var index = i;
        InteractiveObjects[index].OnOver += () => {
            foreach (MeshRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<MeshRenderer>())
            {
                renderer.enabled = true;
            }

            foreach (SpriteRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<SpriteRenderer>())
            {
                renderer.enabled = true;
            }
        };

        InteractiveObjects[index].OnOut += () => {
            foreach (MeshRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<MeshRenderer>())
            {
                renderer.enabled = false;
            }

            foreach (SpriteRenderer renderer in InteractiveObjects[index].GetComponentsInChildren<SpriteRenderer>())
            {
                renderer.enabled = false;
            }
        };
    }
}
...