编辑
2022-06-20
Unity游戏开发
00
请注意,本文编写于 461 天前,最后修改于 105 天前,其中某些信息可能已经过时。

目录

任意点传送 —— Area
锚点传送 —— Anchor
手柄控制视角 —— SnapTurnProvider
隔空取物组件 —— XR Grab Interactable
握住把手/开关门
C#脚本/手柄交互
2D UI绘制与界面
射线点击事件回调

最近入手了心仪已久的 VR-Pico Neo 3,价格还不错1900¥拿下,希望 Neo 4晚点出来哈,不然感觉会亏死!基于 Unity 引擎的基础 XR 场景,主要熟悉了一下Pico的SDK引入,手柄交互控制,2D UI交互之类的API。体验了一下其实用起来还蛮简单的,官方文档嘛一言难尽,先看看下面这些Demo呗。

基于PicoVR设备进行VR开发,记录几个Demo Code,用时随时查阅此博客和官方手册。

PicoVR SDK下载地址:https://sdk.picovr.com/developer-platform/sdk

PackageManager 安装插件:

设置Player的中的参数:Android API版本,L2CPP,ARM V8,XR Plugin选择Android,Build And Run选设备:

任意点传送 —— Area

新建地面 Plane,然后给地面标记可以传送:

XR Rig 就是表示玩家自己,XR Rig 就是Plane的Teleprotaion

XR Rig的组件属性设定如下:

Locomotion System组件就是负责整个玩家的移动,Provided只负责将Locomotion System和传送目标点绑定。

关于手柄的一些设置,比如设置射线颜色,触发按钮等等:

锚点传送 —— Anchor

Teleprotaion Anchor 用于锚点传送

如果需要改变传送的位置,先创建空对象,在把Teleprotaion Anchor Transform 设置为创建的空对象即可。

手柄控制视角 —— SnapTurnProvider

XR Rig添加SnapTurnProvider组件,指定控制移动的System即可:

隔空取物组件 —— XR Grab Interactable

地面需要开启碰撞,同时物体最好也设置刚体属性,扔出去的速度调节:Throw Velocity Scale

握住把手/开关门

先建造一个门,然后需要把手柄的射线给取消掉,即 XR Ray Interactor 这个组件需要被移除掉,同时下面两个组件 XR Interactor Line Visual 和 Line Renderer是用来描述射线的,也需要被移除。

给右手手柄添加碰撞器和手柄和交互器,同时为了表示左右手的模型,把手形状的预制体加进去,在 Packages - XR Plugin下面的 Prefab下可以找到:

C#脚本/手柄交互

用左手手柄控制小球运动的Demo Code:

c#
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR; using UnityEngine.XR.Interaction.Toolkit; public class PicoControllerOne : MonoBehaviour { public XRController leftController; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { // 获取左手控制器 Vector2 result; bool success = leftController.inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out result); if (success) { Vector3 position = transform.position; // Time.deltaTime 帧间时间:为了移动更加平滑 float value = 0.2f; transform.position = new Vector3(position.x + result.x * value * Time.deltaTime, position.y, position.z + result.y * value * Time.deltaTime); } // 握把键按下的值为多少(0 - 1之间的值) leftController.inputDevice.TryGetFeatureValue(CommonUsages.grip, out float floatResult); // 菜单键 leftController.inputDevice.TryGetFeatureValue(CommonUsages.menuButton, out bool menuClicked); // 用这种方式也是OK的 InputHelpers.IsPressed(leftController.inputDevice, InputHelpers.Button.Grip, out menuClicked, 0.8f); } }

2D UI绘制与界面

XR -> 创建Canvas

2D UI的点击事件,其实很简单和平时的Unity开发没什么两样,先弄一个空物体挂上脚本,里面写好点击事件回调或者其他回调,然后在Unity里绑定即可:

c#
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UIController : MonoBehaviour { public Text NumberText; public Slider NumberSlider; public void addNumberClick() { int num = Int32.Parse(NumberText.text); NumberText.text = num + 1 + ""; } public void subNumberClick() { int num = Int32.Parse(NumberText.text); NumberText.text = num - 1 + ""; } public void SliderChange(Single value) { NumberText.text = value + ""; } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }

射线点击事件回调

XR Grab Interactable 会有抓取的效果,但是 XR Simple Interactable就只有回调,而不是抓取。

射线为照射到小球为灰色,照射到时为蓝色,按下为红色,取消变为蓝色,射线不照射小球恢复灰色的例子:

c#
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; public class SimpleInteractController : MonoBehaviour { public GameObject gameObject; public Material blue, red, grey, green, yellow; // 选中点击按住 public void onSelected(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = red; } // 选中点击松开 public void onDeSelected(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = blue; } // 射线悬停在球上的时候 public void onHoverEnter(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = blue; } // 射线取消悬停在球上的时候 public void onHoverExit(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = grey; } // 选中时按下Trigger进入Active public void onActived(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = yellow; } // 选中时松开Trigger进入DeActive public void onDeActived(XRBaseInteractor interactor) { gameObject.GetComponent<MeshRenderer>().material = green; } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }

本文作者:Tim

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!