Unity VR中的滑块
我们正在开发Go的video播放器应用程序。 我们构建了一个简单的raycaster脚本,当用户指向UI Button元素并触发触发器时触发onClick事件:
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
我们真的希望能够使用激光指示器和按钮操纵UI滑块,但不清楚我们是否可以触发适当行为的类似事件。 我们可以调用onValueChanged
来改变值,但这并没有真正给我们提供我们想要的滑动行为,只有让我们知道了我们最终会在哪里设置新值。
有没有人对如何处理这个有好的想法?
Oculus Integration有一个名为OVRInputModule.cs
的脚本。 我相信这是为你想要做的而设计的。 为了做到这一点,有几个步骤。 GIF的结果。
为此,我将代码分成三个脚本; ControllerInfo
, ControllerPointer
和SetUITransformRay
。
控制器信息只是一个类,可确保脚本始终具有正确的信息。
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
从ControllerPointer
绘制一条线。 这表示控制器指向的方式。 将其添加到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(); 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
光线设置控制器。 通常你需要在你的场景中有两个控制器; 左边一个,右边一个。 有关如何进行此设置的详细信息,请参阅下面的完整方法。 将此组件添加到添加canvas时生成的EventSystem
。
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 Integration包。 将OVRCameraRig
拖到场景中。 将OVRTrackedRemote
拖动到左侧和右侧锚点。 根据锚点将每个遥控器设置为向左或向右。
步骤2)设置canvas和事件系统。
在canvas上,
在EventSystem上,
步骤3)设置正确的对象
创建3个对象; Controller Manager
, Controller Pointer
和OVRGazePointer
。
对于OVRGazePointer
,我很快就进入了UI, Oculus\VR\Scenes
的示例Oculus\VR\Scenes
,并在那里预制了OVRGazePointer
。
在控制器指针上,有一个LineRenderer
。 这有两点,无所谓。 它使用世界空间 。 它的宽度为0.005。
只有两点,并使用世界空间是非常重要的 。 这是因为ControllerPointer
脚本依赖于那两个被设置的脚本。
我不知道这是否有帮助,但我强烈建议检查这两个sdks:
第一个是GoogleVR sdk ,您可以查看事件系统以及他们如何实现他们的光线投影系统并将其与统一集成。
第二个是“基本UI场景”中的跳跃动作交互引擎 。 他们使用物理实现了滚动条,因此您可以使用手与它进行交互。 你可以检查一下我觉得它会非常有用。
后来我发现Oculus的这篇博文提供了一些很棒的代码和例子; 它类似于丹的答案,但更加透彻,并有可下载的示例。
https://developer.oculus.com/blog/easy-controller-selection/