n 秒后注视触发事件 - Unity

gaze trigger event after n seconds - Unity

我有一个 'pointer enter' 事件,但我只希望在注视对象上持续 n 秒时触发该事件。

public void PointerEnter() {
   // change scene if the gaze point have been active for n seconds.
}

无论如何要实现这个?

仅仅有一个超时是行不通的,因为它仍然会执行,而不是指针是否锁定在对象上。

您可以使用布尔变量通过将其设置为 true 和 false 来保持指针何时进入和退出的状态。然后可以在 Update 函数中检查此布尔变量。当为true时,启动一个定时器,如果在定时器期间变为false,则将定时器重置为0。检查计时器何时超过 x 秒然后加载新场景。

下面的示例假定当指针指向时调用 PointerEnter,当指针不再指向时调用 PointerExit。根据您使用的 VR 插件,功能可能会有所不同,但其余代码是相同的。

const float nSecond = 2f;

float timer = 0;
bool entered = false;

public void PointerEnter()
{
    entered = true;
}

public void PointerExit()
{
    entered = false;
}

void Update()
{
    //If pointer is pointing on the object, start the timer
    if (entered)
    {
        //Increment timer
        timer += Time.deltaTime;

        //Load scene if counter has reached the nSecond
        if (timer > nSecond)
        {
            SceneManager.LoadScene("SceneName");
        }
    }
    else
    {
        //Reset timer when it's no longer pointing
        timer = 0;
    }
}

您根本不需要为此使用指针事件,而是使用简单的光线投射。这样做的好处是,您还可以将它与图层蒙版、标签或任何其他您想要用来识别一组对象的东西结合使用,并且您不需要在 运行 上设置指针事件 运行您希望凝视的每个对象。但只需要在 VRhead 或 raycaster 上安装一个脚本即可。

在我的示例中,我将使用图层蒙版。这将使凝视作用于同一层中的任何对象,如 "uiButton"

public sceneIndex = 0; //build index of the scene you want to switch to

private Ray ray;
private RaycastHit hit;
[serializefield]
private LayerMask myMask;//serializing it will give a dropdown menu in the editor to select the mask layer form, can also use int to select the layer

private readonly float rayLength = 10;
private readonly float timerMax = 5f; //Higher timerMax is a longer wait, lower timerMax is shorter...
private float timer = 0f;

private void Update()
{
    ray = Camera.main.ViewportPointToRay(Vector3.forward);
    if (Physics.Raycast(ray, out hit, rayLength, myMask))
    {
        timer += Time.deltaTime;
        if(timer >= timerMax)
        {
            SceneManager.LoadScene(sceneIndex);//load the scene with the build index of sceneIndex
        }
    }
    else
    {
        timer = 0;
    }
}

只要你在光线投射器的长度范围内观察与myMask timer在同一层上的物体,它就会不断增加,直到它大于或等于timerMax,满足这个条件就会改变场景