赞
踩
随着Pico被字节收购,追踪优化变好了,Pico的串流也越来越好用了,现在已经可以用于开发了,现在所用的设备为Pico Neo3消费版,个人感觉的使用感受是,比起上万的HTC Vive设备,几千的Pico Neo3消费版,某种程度来说是更加好用的,现在我要介绍的VR开发框架为VRIF,全称为VR Interaction Framework。
VRIF插件获取:Unity商店
VRIF官网:VRIF Wiki
1、它适合用多个平台,基本上来说,一次开发就可以打包到大部分的主流的平台,如:PC VR设备、Pico设备、Oculus设备等。
2、得益于Openxr和XR Interaction Toolkit的一致性,而VRIF又集成了XR Interaction Toolkit输入输出,所以它可以做到串流调式和Pico打包无缝衔接。
3、开发速度快,VRIF已经在案例中实现了很多VR开发的常用功能,只要拿来用就行。
4、作者更新快,目前已更新到了2.0,集成了 FinalIK和PhotonPUN 示例。
5、Unity主推,经测试此框架,适配了Pico Neo3/Pico Neo4系例设备
串流调式和Pico打包无缝衔接的实现基于OpenXR+XR Interaction Toolkit这方案,现在Pico最新版SDK就是此进行开发的,而Openxr和XR Interaction Toolkit这方案也适用于HTC vive和Oculus的串流。
可以理解为大框架,先导入大框架,然后根据要用到的设备导入相应的Sdk,这样就可以多种设备一次切换,打出多个包。
安装完要重启,Untiy改变输入类型都是要重启的,选Yes.
双击VRIF2.0包导入:
这样VRIF就导入完成了。
打开PackageManager,点击+号,选择Add package by name。然后输入:com.unity.xr.interaction.toolkit
导入XR Interaction Toolkit插件,并更新
导入Text Mesh Pro插件
导入默认的动作绑定资产
修改这两项,第二个一定要选Oculus Touch Controller Profile,在Pico串流的情况手柄才能追踪,选了HTC ViveController Profile会手柄追踪不了的。
设置VRIF的输入输出,也可什么也不勾,一样能正常使用,UI射线也不会有问题。
好了,现在运行这个XR Demo,用Pico串流就可以走SteamVR平台来流玩这个场景了
勾选了XR Interaction Toolkit,会导致UI射线有问题,则:
取消勾选后,VRIF的射线就没问题了
去官网下载最新的SDK
解压并将此包放到项目的Assets同级目录下,防止此包某天被删除,再打开就报错了。
打开PackageManager,点击+号,选择Add package by disl.....。然后找到此包并导入,导入后Apply一下
勾选Pico
最后,打包
现在打包出来Pico就可以使用了
之前已经打包了Pico平台了,现在打包Oculus设备
安装Oculus XR Plugin插件
取消勾选Pico,勾选OCulus直接打包就可以了
打包SteamVR,切换成window平台,要在BNG Framework/Integrations/SteamVR/SteamVR路径里面,导入一个包用于StamVR输入,试一下打包,不行再导入SteamVr2.0整个包,请参考:VR Interaction Framework插件的使用_vrif-CSDN博客文章浏览阅读2.8k次,点赞3次,收藏22次。随着VR技术越来越成熟,Untiy版本的不断更新,steamVR和VRTK等旧版本插件不再完美适配最新版本的Unity编辑器,编辑器和插件经常各种报错,推荐使用VRIF进行VR开发,该框架使可以轻松创建自己的交互对象并快速提高工作效率,最大的优势是可以支持所有与 Unity 兼容的 VR眼镜并且和各种新版本Unity编辑器兼容性好。本文主要记录VRIF的环境搭建,基于SteamVR的HTC设备一、软件和插件的获取软件建议使用一个长期支持(LTS)版本的Unity,比较稳定,并且有广泛的支持。对于大多_vrifhttps://blog.csdn.net/weixin_44733991/article/details/125034189?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170391688816800182774826%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170391688816800182774826&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-125034189-null-null.142^v99^pc_search_result_base6&utm_term=vrif&spm=1018.2226.3001.4187
当按下按钮后,不抬起来,Button的颜色变不回来
修改VRIF的VRUISystem的源码
修改为,下面这样的:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.InputSystem;
- using UnityEngine.UI;
-
- namespace BNG
- {
-
- public class VRUISystem : BaseInputModule
- {
-
- [Header("XR Controller Options : ")]
- [Tooltip("This setting determines if LeftPointerTransform or RightPointerTransform will be used as a forward vector for World Space UI events")]
- public ControllerHand SelectedHand = ControllerHand.Right;
-
- #if XRIT_INTEGRATION
- [Header("XR Interaction Toolkit Options : ")]
- public bool UseXRInteractionToolkitUISystem = true;
-
- #endif
-
- [Tooltip("A transform on the left controller to use when raycasting for world space UI events")]
- public Transform LeftPointerTransform;
-
- [Tooltip("A transform on the right controller to use when raycasting for world space UI events")]
- public Transform RightPointerTransform;
-
- [Tooltip("Controller Binding to use for input down, up, etc.")]
- public List<ControllerBinding> ControllerInput = new List<ControllerBinding>() { ControllerBinding.RightTrigger };
-
- [Tooltip("Unity Input Action used to simulate a click or touch event")]
- public InputActionReference UIInputAction;
-
- [Tooltip("If true a PhysicsRaycaster component will be added to the UI camera, allowing physical objects to use IPointer events such as OnPointClick, OnPointEnter, etc.")]
- public bool AddPhysicsRaycaster = false;
-
- public LayerMask PhysicsRaycasterEventMask;
-
- [Tooltip("If true the Right Thumbstick will send scroll events to the UI")]
- public bool RightThumbstickScroll = true;
-
- [Header("Shown for Debug : ")]
- public GameObject PressingObject;
- public GameObject DraggingObject;
- public GameObject ReleasingObject;
-
- public PointerEventData EventData { get; private set; }
-
- Camera cameraCaster;
-
- private GameObject _initialPressObject;
- private bool _lastInputDown;
- bool inputDown;
-
- private static VRUISystem _instance;
- public static VRUISystem Instance
- {
- get
- {
- if (_instance == null)
- {
- _instance = GameObject.FindObjectOfType<VRUISystem>();
-
- if (_instance == null)
- {
- // Check for existing event system
- EventSystem eventSystem = EventSystem.current;
- if (eventSystem == null)
- {
- eventSystem = new GameObject("EventSystem").AddComponent<EventSystem>(); ;
- }
-
- _instance = eventSystem.gameObject.AddComponent<VRUISystem>();
- }
- }
-
- return _instance;
- }
- }
-
- protected override void Awake()
- {
- #if XRIT_INTEGRATION
- if(!UseXRInteractionToolkitUISystem) {
- initEventSystem();
- }
- #else
- initEventSystem();
- #endif
- }
-
- protected virtual void initEventSystem()
- {
- UpdateControllerHand(SelectedHand);
-
- AssignCameraToAllCanvases(cameraCaster);
-
- EventData = new PointerEventData(eventSystem);
- EventData.position = new Vector2(cameraCaster.pixelWidth / 2, cameraCaster.pixelHeight / 2);
- }
-
- protected override void Start()
- {
- base.Start();
-
- #if XRIT_INTEGRATION
- if (UseXRInteractionToolkitUISystem) {
- AssignCameraToAllCanvases(Camera.main);
-
- if (this.gameObject.activeSelf) {
- // Debug.Log("Diabling VRIF's VRUISystem since XR Interaction Kit UI support is enabled");
- this.enabled = false;
- }
- }
- #else
- AssignCameraToAllCanvases(cameraCaster);
- #endif
- }
-
- void init()
- {
- if (cameraCaster == null)
- {
-
- // Create the camera required for the caster.
- // We can reduce the fov and disable the camera component for performance
- var go = new GameObject("CameraCaster");
- cameraCaster = go.AddComponent<Camera>();
- cameraCaster.stereoTargetEye = StereoTargetEyeMask.None;
- cameraCaster.fieldOfView = 5f;
- cameraCaster.nearClipPlane = 0.01f;
- cameraCaster.clearFlags = CameraClearFlags.Nothing;
- cameraCaster.enabled = false;
-
- // Add PhysicsRaycaster so other objects can subscribe to IPointer events
- if (AddPhysicsRaycaster)
- {
- var pr = go.AddComponent<PhysicsRaycaster>();
- pr.eventMask = PhysicsRaycasterEventMask;
- }
- }
- }
-
- public override void Process()
- {
- #if XRIT_INTEGRATION
- // XRIT doesn't process here
- if(UseXRInteractionToolkitUISystem == false) {
- DoProcess();
- }
- #else
- DoProcess();
- #endif
- }
-
- public void DoProcess()
- {
- // Input isn't ready if this Camera Caster's gameObject isn't active
- if (EventData == null || !CameraCasterReady())
- {
- return;
- }
-
- EventData.position = new Vector2(cameraCaster.pixelWidth / 2, cameraCaster.pixelHeight / 2);
-
- eventSystem.RaycastAll(EventData, m_RaycastResultCache);
-
- EventData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
- m_RaycastResultCache.Clear();
-
- // Handle Hover
- HandlePointerExitAndEnter(EventData, EventData.pointerCurrentRaycast.gameObject);
-
- // Handle Drag
- ExecuteEvents.Execute(EventData.pointerDrag, EventData, ExecuteEvents.dragHandler);
-
- // Handle scroll
- if (RightThumbstickScroll)
- {
- EventData.scrollDelta = InputBridge.Instance.RightThumbstickAxis;
- if (!Mathf.Approximately(EventData.scrollDelta.sqrMagnitude, 0))
- {
- ExecuteEvents.Execute(ExecuteEvents.GetEventHandler<IScrollHandler>(EventData.pointerCurrentRaycast.gameObject), EventData, ExecuteEvents.scrollHandler);
- }
- }
-
- // Press Events
- inputDown = InputReady();
-
- // On Trigger Down > TriggerDownValue this frame but not last
- if (inputDown && _lastInputDown == false)
- {
- PressDown();
- }
- // On Held Down
- else if (inputDown)
- {
- //Press();
- }
- // On Release
- else
- {
- Release();
- }
-
- _lastInputDown = inputDown;
- }
-
- public virtual bool InputReady()
- {
-
- // Input isn't ready if this Camera Caster's gameObject isn't active
- if (!CameraCasterReady())
- {
- return false;
- }
-
- // Check Unity Action
- if (UIInputAction != null && UIInputAction.action.ReadValue<float>() == 1f)
- {
- return true;
- }
-
- // Check for bound controller button
- for (int x = 0; x < ControllerInput.Count; x++)
- {
- if (InputBridge.Instance.GetControllerBindingValue(ControllerInput[x]))
- {
- return true;
- }
- }
-
- return false;
- }
-
-
- /// <summary>
- /// Returns true if we have a camera caster enabled and ready to send out data
- /// Returns false if the camera caster is null or it's gameobject is disabled
- /// </summary>
- /// <returns></returns>
- public virtual bool CameraCasterReady()
- {
- if (cameraCaster != null && !cameraCaster.gameObject.activeInHierarchy)
- {
- return false;
- }
-
- return true;
- }
-
- public virtual void PressDown()
- {
- EventData.pointerPressRaycast = EventData.pointerCurrentRaycast;
-
- // Deselect if selection changed
- if (_initialPressObject != null)
- {
- ExecuteEvents.Execute(_initialPressObject, EventData, ExecuteEvents.deselectHandler);
- _initialPressObject = null;
- }
-
- _initialPressObject = ExecuteEvents.GetEventHandler<IPointerClickHandler>(EventData.pointerPressRaycast.gameObject);
-
- // Set Press Objects and Events
- SetPressingObject(_initialPressObject);
- ExecuteEvents.Execute(EventData.pointerPress, EventData, ExecuteEvents.pointerDownHandler);
-
- // Set Drag Objects and Events
- SetDraggingObject(ExecuteEvents.GetEventHandler<IDragHandler>(EventData.pointerPressRaycast.gameObject));
- ExecuteEvents.Execute(EventData.pointerDrag, EventData, ExecuteEvents.beginDragHandler);
- }
-
- public virtual void Press()
- {
- EventData.pointerPressRaycast = EventData.pointerCurrentRaycast;
-
- // Set Press Objects and Events
- SetPressingObject(ExecuteEvents.GetEventHandler<IPointerClickHandler>(EventData.pointerPressRaycast.gameObject));
- ExecuteEvents.Execute(EventData.pointerPress, EventData, ExecuteEvents.pointerDownHandler);
-
- // Set Drag Objects and Events
- SetDraggingObject(ExecuteEvents.GetEventHandler<IDragHandler>(EventData.pointerPressRaycast.gameObject));
- ExecuteEvents.Execute(EventData.pointerDrag, EventData, ExecuteEvents.beginDragHandler);
- }
-
- public virtual void Release()
- {
- SetReleasingObject(ExecuteEvents.GetEventHandler<IPointerClickHandler>(EventData.pointerCurrentRaycast.gameObject));
- // Considered a click event if released after an initial click
- if (EventData.pointerPress == ReleasingObject)
- {
- ExecuteEvents.Execute(EventData.pointerPress, EventData, ExecuteEvents.pointerClickHandler);
- }
- ExecuteEvents.Execute(EventData.pointerPress, EventData, ExecuteEvents.pointerUpHandler);
- ExecuteEvents.Execute(EventData.pointerDrag, EventData, ExecuteEvents.endDragHandler);
- // Send deselect to
- ExecuteEvents.Execute(ReleasingObject, EventData, ExecuteEvents.deselectHandler);
- ClearAll();
- }
-
- public virtual void ClearAll()
- {
- SetPressingObject(null);
- SetDraggingObject(null);
-
- EventData.pointerCurrentRaycast.Clear();
- }
-
- public virtual void SetPressingObject(GameObject pressing)
- {
- EventData.pointerPress = pressing;
- PressingObject = pressing;
- }
-
- public virtual void SetDraggingObject(GameObject dragging)
- {
- EventData.pointerDrag = dragging;
- DraggingObject = dragging;
- }
-
- public virtual void SetReleasingObject(GameObject releasing)
- {
- ReleasingObject = releasing;
- }
-
- public virtual void AssignCameraToAllCanvases(Camera cam)
- {
- Canvas[] allCanvas = FindObjectsOfType<Canvas>();
- for (int x = 0; x < allCanvas.Length; x++)
- {
- AddCanvasToCamera(allCanvas[x], cam);
- }
- }
-
- public virtual void AddCanvas(Canvas canvas)
- {
- #if XRIT_INTEGRATION
- if(UseXRInteractionToolkitUISystem) {
- AddCanvasToCamera(canvas, Camera.main);
-
- // Add raycaster if not already present
- canvas.gameObject.AddComponent<UnityEngine.XR.Interaction.Toolkit.UI.TrackedDeviceGraphicRaycaster>();
- }
- else {
- AddCanvasToCamera(canvas, cameraCaster);
- }
- #else
- AddCanvasToCamera(canvas, cameraCaster);
- #endif
- }
-
- public virtual void AddCanvasToCamera(Canvas canvas, Camera cam)
- {
- if (cam != null)
- {
- canvas.worldCamera = cam;
- }
- }
-
- public virtual void UpdateControllerHand(ControllerHand hand)
- {
-
- // Make sure variables exist
- init();
-
- // Setup the Transform
- if (hand == ControllerHand.Left && LeftPointerTransform != null)
- {
- cameraCaster.transform.parent = LeftPointerTransform;
- cameraCaster.transform.localPosition = Vector3.zero;
- cameraCaster.transform.localEulerAngles = Vector3.zero;
- }
- else if (hand == ControllerHand.Right && RightPointerTransform != null)
- {
- cameraCaster.transform.parent = RightPointerTransform;
- cameraCaster.transform.localPosition = Vector3.zero;
- cameraCaster.transform.localEulerAngles = Vector3.zero;
- }
- }
- }
- }
Button的导航选为None,这个在Andoroid上点用都没有,还会导致UGUI有Bug
这样VRIF的交互与UGUI就行了,射线进入为Highlighted Color,按下为Pressed Color,Selected Color不触发。
现在Bug就解决了,也实现了一次开发多个平台的分发,也可以串流实时调式了,如果是Pico要应用加密,则在XR Rig Advanced加上PXR Manager脚本就行了。
完结!!!
撒花!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。