Sea*_*ins 5 c# unity-game-engine virtual-reality
我们正在开发适用于 Go 的视频播放器应用程序。我们构建了一个简单的 raycaster 脚本来在用户指向 UI 按钮元素并拉动触发器时触发 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<Button>();
if (button != null)
{
button.onClick.Invoke();
}
}
....
}
Run Code Online (Sandbox Code Playgroud)
我们真的希望能够使用激光笔和按钮来操作 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;
}
}
Run Code Online (Sandbox Code Playgroud)
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<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;
}
}
Run Code Online (Sandbox Code Playgroud)
SetUITransformRay将自动设置光线的控制器OVRInputModule。这是必需的,因为通常场景中有两个控制器;一个为左,一个为右。有关如何设置的更多信息,请参阅下面的完整方法。将此组件添加到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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用步骤
步骤1)场景设置
导入 Oculus 集成包。将其拖到OVRCameraRig您的场景中。将 a 拖入OVRTrackedRemote左右锚点。根据锚点将每个遥控器设置为左侧或右侧。
步骤 2) 设置画布和事件系统。
在画布上,
在事件系统上,
步骤 3) 设置正确的对象
创建3个对象;Controller Manager,Controller Pointer, 和OVRGazePointer。
对于OVRGazePointer,我只是快速进入 UI 的示例场景,Oculus\VR\Scenes并在那里预制OVRGazePointer。
在控制器指针上,有一个LineRenderer. 这有两点,无论在哪里。它使用世界空间。它的宽度为 0.005。
只有两个点,利用世界空间非常重要。这是因为ControllerPointer脚本依赖于这两个设置。
| 归档时间: |
|
| 查看次数: |
3667 次 |
| 最近记录: |