Unity VR中具有OnOver和OnOut(C#)的交互式对象

时间:2019-02-05 15:48:51

标签: c# unity3d interactive virtual-reality oculus

Printscreen from Unity 我正在Unity for Oculus Go中创建一个VR应用程序。 我想在精灵上显示一些文字,同时激光笔悬停在某些游戏对象上,而在没有时消失。我正在尝试通过创建一个数组来做到这一点,当激光指示器悬停在特定对象上时,该数组应该显示特定游戏对象组件(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;
        }

}

}

我如何让激光指示器知道我正在与哪个特定游戏对象进行交互并使其仅显示该对象的组件?我曾尝试找到具有ID的解决方案,但尚未在VR中使用它。

1 个答案:

答案 0 :(得分:0)

如前所述,我实际上建议让每个VRInteractiveItem处理OnOver本身,而不是从一个管理器组件中全部完成。


但是,您可以做的一件事(尽管我不建议),是使用带有for循环而不是foreach的lambda表达式作为回调而不是类似的方法

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