本文介绍了Unity VR中的滑块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在为Go开发视频播放器应用.我们构建了一个简单的raycaster脚本,以在用户指向UI Button元素并拉动触发器时触发onClick事件:

We're working on a video player app for the Go. We built a straightforward raycaster script to trigger onClick events when a user points at a UI Button element and pulls the trigger:

bool triggerPulled = OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger);
    if (Physics.Raycast(transform.position, transform.forward, out hit, 1000))
    {

        if ( triggerPulled )
        {

            // if we hit a button
            Button button = hit.transform.gameObject.GetComponent<Button>();

            if (button != null)
            {
                button.onClick.Invoke();
            }

        }
....
    }

我们真的很希望能够使用激光指示器和按钮来操纵UI滑块,但是尚不清楚我们是否可以为适当的行为触发类似事件.我们可以调用onValueChanged来更改值,但这并没有真正给我们想要的滑动行为,仅当我们知道要在哪里结束时才让我们设置新值.

We'd really like to be able to manipulate UI Sliders with the laser pointer as well as buttons, but aren't clear on whether there are analogous events we can trigger for the appropriate behavior. We can call onValueChanged to alter the value, but that doesn't really give us the sliding behavior we'd like, only lets us set the new value once we know where we're ending up.

有人对如何解决这个问题有好主意吗?

Does anybody have good ideas for how to approach this?

推荐答案

Oculus Integration 有一个名为OVRInputModule.cs的脚本.我相信这是针对您要尝试执行的操作而设计的.为此,需要执行一些步骤.结果的GIF.

Oculus Integration has a script called OVRInputModule.cs. I believe this is designed for what you are trying to do. In order to do this there are a few steps. A GIF of the result.

为实现这一点,我将代码分为三个脚本. ControllerInfoControllerPointerSetUITransformRay.

To achieve this, I split the code into three scripts; ControllerInfo, ControllerPointer, and SetUITransformRay.

控制器信息只是一个确保脚本始终具有正确信息的类.

Controller info is just a class that makes sure that scripts always have the correct information.

using UnityEngine;
using static OVRInput;

public class ControllerInfo : MonoBehaviour {
    [SerializeField]
    private Transform trackingSpace;
    public static Transform TRACKING_SPACE;
    public static Controller CONTROLLER;
    public static GameObject CONTROLLER_DATA_FOR_RAYS;

    private void Start () {
        TRACKING_SPACE = trackingSpace;
    }

    private void Update()
    {
        CONTROLLER = ((GetConnectedControllers() & (Controller.LTrackedRemote | Controller.RTrackedRemote) & Controller.LTrackedRemote) != Controller.None) ? Controller.LTrackedRemote : Controller.RTrackedRemote;
    }
}

ControllerPointer从控制器绘制一条线.这代表控制器指向的方式.将此添加到LineRenderer.

ControllerPointer draws a line from the controller. This represents the way the controller is pointing. Add this to a LineRenderer.

using UnityEngine;
using UnityEngine.EventSystems;
using static OVRInput;

[RequireComponent(typeof(LineRenderer))]
public class ControllerPointer : MonoBehaviour
{
    [SerializeField]
    private SetUITransformRay uiRays;
    private LineRenderer pointerLine;
    private GameObject tempPointerVals;

    private void Start()
    {
        tempPointerVals = new GameObject();
        tempPointerVals.transform.parent = transform;
        tempPointerVals.name = "tempPointerVals";
        pointerLine = gameObject.GetComponent<LineRenderer>();
        pointerLine.useWorldSpace = true;

        ControllerInfo.CONTROLLER_DATA_FOR_RAYS = tempPointerVals;
        uiRays.SetUIRays();
    }

    private void LateUpdate()
    {
        Quaternion rotation = GetLocalControllerRotation(ControllerInfo.CONTROLLER);
        Vector3 position = GetLocalControllerPosition(ControllerInfo.CONTROLLER);
        Vector3 pointerOrigin = ControllerInfo.TRACKING_SPACE.position + position;
        Vector3 pointerProjectedOrientation = ControllerInfo.TRACKING_SPACE.position + (rotation * Vector3.forward);
        PointerEventData pointerData = new PointerEventData(EventSystem.current);
        Vector3 pointerDrawStart = pointerOrigin - pointerProjectedOrientation * 0.05f;
        Vector3 pointerDrawEnd = pointerOrigin + pointerProjectedOrientation * 500.0f;
        pointerLine.SetPosition(0, pointerDrawStart);
        pointerLine.SetPosition(1, pointerDrawEnd);

        tempPointerVals.transform.position = pointerDrawStart;
        tempPointerVals.transform.rotation = rotation;
    }
}

SetUITransformRay将自动为OVRInputModule射线设置控制器.通常,场景中有两个控制器是必需的.一为左,一为右.有关如何进行设置的更多信息,请参见下面的完整方法.将此组件添加到添加画布时生成的EventSystem中.

SetUITransformRay will automatically set the controller for the OVRInputModule ray. It is required as normally you have two controllers in your scene; one for left and one for right. See the full method below for more info on how to set this up. Add this component to your EventSystem that is generated when you add a canvas.

using UnityEngine;
using UnityEngine.EventSystems;

public class SetUITransformRay : MonoBehaviour
{
    [SerializeField]
    private OVRInputModule inputModule;
    [SerializeField]
    private OVRGazePointer gazePointer;

    public void SetUIRays()
    {
        inputModule.rayTransform = ControllerInfo.CONTROLLER_DATA_FOR_RAYS.transform;
        gazePointer.rayTransform = ControllerInfo.CONTROLLER_DATA_FOR_RAYS.transform;
    }
}


使用步骤

第1步:场景设置

导入Oculus集成包.将OVRCameraRig拖到场景中.将OVRTrackedRemote拖到左侧和右侧锚点中.根据锚点将每个遥控器设置为左或右.

Import the Oculus Integration pack. Drag the OVRCameraRig onto your scene. Drag a OVRTrackedRemote into the left and right hand anchors. Set each remote to left or right depending on the anchor.

第2步)设置画布和事件系统.

Step 2) Set up your canvas and eventsystem.

在画布上,

在事件系统上,

第3步)设置正确的对象

Step 3) Set up correct objects

创建3个对象; Controller ManagerController PointerOVRGazePointer.

Create 3 objects; Controller Manager, Controller Pointer, and OVRGazePointer.

对于OVRGazePointer,我很快进入了UI Oculus\VR\Scenes的示例场景,并在其中预制了OVRGazePointer.

For the OVRGazePointer, I just quickly went in the example scene for UI, Oculus\VR\Scenes, and prefabed the OVRGazePointer there.

在控制器指针上,有一个LineRenderer.这有两个点,无论在哪里.它使用世界空间.宽度为0.005.

On Controller Pointer, there is a LineRenderer. This has two points, doesn't matter where. It uses world space. It has a width of 0.005.

只有两点,并且使用世界空间非常重要.这是因为ControllerPointer脚本依赖于像这样设置的那两个.

Only having two points, and using world space is very important. This is because ControllerPointer the script relies on those two being set like that.

这篇关于Unity VR中的滑块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:43