由于Unity软件对VR插件的兼容性问题使得实际项目中对于VR插件的使用限制很大,官方对于SteamVR插件的兼容性是最稳定的,SteamVR插件的示例场景里面对于UI的交互是使用的手柄触摸的方式,在Button上还添加Box Collider,这太麻烦了。
下面我们使用手柄射线交互的UI的方式

本文主要记录实现的方法,具体原理这里不做说明,插件从商店导入到unity,插件导入之后没有报错即是没有问题,找到VR预制体Player加入到场景里面,第一步新建脚本VRInputModel,该脚本不需要添加在任何物体上,代码如下:

using UnityEngine;
using UnityEngine.EventSystems;public class VRInputModel : BaseInputModule
{/// <summary>/// 事件摄像机/// </summary>private Camera eventCamera;/// <summary>/// 是否检测射线/// </summary>public bool isActive = true;/// <summary>/// 是否执行UI操作标志位/// </summary>public bool isExecute = false;/// <summary>/// 指针事件数据/// </summary>public PointerEventData Data { get; private set; } = null;protected override void Awake(){eventCamera = GetComponent<Camera>();}protected override void Start(){Data = new PointerEventData(eventSystem);//设定射线的起始点为事件相机的视窗中心Data.position = new Vector2(eventCamera.pixelWidth / 2, eventCamera.pixelHeight / 2);}public override void Process(){if (isActive){//发射射线检测UIeventSystem.RaycastAll(Data, m_RaycastResultCache);//从由近到远的射线碰撞结果m_RaycastResultCache中获取第一个(最近)的碰撞结果对应的射线结果Data.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);//先处理射线点进入或移出UI游戏物体(这个事件让继承IPointerEnterHandler和IPointerExitHandler中的事件触发)HandlePointerExitAndEnter(Data, Data.pointerCurrentRaycast.gameObject);Debug.Log(Data.pointerCurrentRaycast.gameObject);//按下点击按钮的标志位if (isExecute){ProcessPress();}else{ProcessRelease();}}}private void ProcessPress(){print("process");//把当前的射线信息赋值给光标按下射线Data.pointerPressRaycast = Data.pointerCurrentRaycast;//把光标按下射线对应的游戏物体赋值给指针数据中的pointPressData.pointerPress = ExecuteEvents.GetEventHandler<IPointerClickHandler>(Data.pointerPressRaycast.gameObject);//执行光标按下事件,该事件会让继承了IPointerClickHandler的派生类中的事件触发ExecuteEvents.Execute(Data.pointerPress, Data, ExecuteEvents.pointerDownHandler);//把光标按下射线对应的游戏物体赋值给指针数据中的pointDragData.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(Data.pointerPressRaycast.gameObject);//执行光标开始拖动事件,该事件会让继承了IIDragHandler的派生类中的事件触发// ExecuteEvents.Execute(Data.pointerDrag, Data, ExecuteEvents.beginDragHandler);ExecuteEvents.Execute(Data.pointerDrag, Data, ExecuteEvents.dragHandler);}private void ProcessRelease(){GameObject pointRelease = ExecuteEvents.GetEventHandler<IPointerClickHandler>(Data.pointerCurrentRaycast.gameObject);if (Data.pointerPress == pointRelease)ExecuteEvents.Execute(Data.pointerPress, Data, ExecuteEvents.pointerClickHandler);ExecuteEvents.Execute(Data.pointerPress, Data, ExecuteEvents.pointerUpHandler);ExecuteEvents.Execute(Data.pointerDrag, Data, ExecuteEvents.endDragHandler);Data.pointerPress = null;Data.pointerDrag = null;Data.pointerCurrentRaycast.Clear();}
}

第二步新建脚本InteractionSys,该脚本需要添加在手柄物体上,代码如下:

using UnityEngine;
using Valve.VR;public class InteractionSys : MonoBehaviour
{private SteamVR_Action_Boolean m_UIPoint;private SteamVR_Action_Boolean m_UIClick;private VRInputModel m_InputModel;LineRenderer m_Line;bool isShowLine = false;private void Awake(){m_UIPoint = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("Teleport");m_UIClick = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("InteractUI");if (m_InputModel == null)m_InputModel = gameObject.AddComponent<VRInputModel>();if (m_Line == null){m_Line = gameObject.AddComponent<LineRenderer>();Keyframe[] ks = new Keyframe[2];ks[0] = new Keyframe(0, 0.007f);ks[1] = new Keyframe(1, 0.007f);m_Line.widthCurve = new AnimationCurve(ks);m_Line.material = new Material(Shader.Find("Unlit/Color"));m_Line.material.SetColor("_Color", new Color32(0, 255, 255, 64));m_Line.SetPosition(0, Vector3.zero);m_Line.SetPosition(1, Vector3.zero);}m_UIPoint.onStateDown += M_UIPoint_onStateDown;m_UIClick.onState += M_UIClick_onState;m_UIClick.onStateUp += M_UIClick_onStateUp;}private void Update(){if (isShowLine){m_Line.SetPosition(0, transform.position);m_Line.SetPosition(1, transform.forward * 10000);}}//圆盘按下private void M_UIPoint_onStateDown(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource){Debug.Log("圆盘按下");//射线开启关闭isShowLine = !isShowLine;m_InputModel.isActive = isShowLine;if (!isShowLine){m_Line.SetPosition(0, Vector3.zero);m_Line.SetPosition(1, Vector3.zero);}}//扳机抬起private void M_UIClick_onStateUp(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource){Debug.Log("扳机抬起");m_InputModel.isExecute = false;}//扳机按下private void M_UIClick_onState(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource){Debug.Log("扳机按下");m_InputModel.isExecute = true;}}

然后,在RightHand上,添加一个Camera组件,并且可以设置enable为false,添加InteractionSys脚本在RightHand上面,同时把Canvas画布上面的RenderMode设置成World Space,把Event Camera赋值成RightHand即可。如下图所示:

InteractionSys是交互逻辑表现,需要哪只手发射线交互,就把这个脚本添加到哪只手上,其他组件会自动添加,比如LineRender、EventSysem、VRInputModel等。

完成!!!

交互方式是按圆盘键呼出射线,扳机键点击交互。

有疑问欢迎vx咨询159-7084-3394

SteamVR使用射线交互UI相关推荐

  1. SteamVR使用射线与UI进行交互

    通过手柄发射射线与UI按钮进行交互 在Button上需要添加的两个脚本和组件 手柄需要准备的内容 在手柄控制器上添加脚本SteamVR_LaserPointer,使得手柄可以发射射线,在创建脚本Las ...

  2. 为SteamVR做射线触发UI

    最近需要在SteamVR上做类似VRTK的射线和UI交互的功能.我自己开发的时候的思路是在右手手柄上加一个LineRender组件,然后从手柄的位置为起点,手柄正方向transform.forward ...

  3. steamvr2.0 + curvedUI 实现与UI射线交互

    2022年8月8日 需求: steamvr2.0以上,要实现与UI的射线交互,目前的方案是结合CurvedUI插件,才能实现次功能,VRTK4.0 虽然也能实现,但其刚推出市场,不成熟,缺乏教程文档, ...

  4. Unity 工具 之 CurvedUI (曲面UI)一些基本操作和CUSTOM_RAY 射线交互时注意事项整理

    Unity 工具 之 CurvedUI(曲面UI) 简单使用介绍和CUSTOM_RAY 射线交互时注意事项整理 目录 Unity 工具 之 CurvedUI(曲面UI) 简单使用介绍和CUSTOM_R ...

  5. PicoXR中手柄射线与UI的交互

    PicoXR中手柄射线与UI的交互 本文将介绍在PicoXR中如何使用手柄射线与UI进行交互 基本步骤 开发Unity XR项目必不可少的要先右键点击Hierarchy面板 XR-Room-Scale ...

  6. VRTK功能教学(二):Unity3DVRTK手柄瞬移和UI交互射线切换功能丨3D模型射线交互切换丨直线和曲线的切换

    VRTK功能教学(二):Unity3DVRTK手柄瞬移和UI交互射线切换功能丨3D模型射线交互切换丨直线和曲线的切换 ` 文章目录 VRTK功能教学(二):Unity3DVRTK手柄瞬移和UI交互射线 ...

  7. SteamVR2.0 UGUI射线交互模拟

    SteamVR2.0 UGUI射线交互模拟 文章目录 SteamVR2.0 UGUI射线交互模拟 前言 一.开始前要做的准备 1.在项目开始前应当把环境给搭建好,在Unity项目中把SteamVR导入 ...

  8. Unity射线与UI碰撞检测

    问题产生背景:我们有的时候,需要实现射线与3D UI之间的碰撞,当射线碰撞到3D UI之后(将Canvas设置为World Space),调整到合适的位置.使用LineRender表示射线的直观显示, ...

  9. Unity SteamVR 2.x UGUI射线交互 +物品射线点击+物品抓起(超级简单)

    刚开始先查看了其他道友的方案:1.Unity使用SteamVR2.0实现基本功能(瞬移,抓取物品,射线点击,UI交互等)_贪小心的博客-CSDN博客_unity steam vr 2.[Steam V ...

最新文章

  1. ios wallet开发_iOS: 使用UICollectionView实现Wallet效果
  2. python快捷键设置_UltraEdit搭建Python IDE环境+设置快捷键
  3. LeetCode 157. 用 Read4 读取 N 个字符
  4. SpringBoot 自动装配原理
  5. wpf datagrid 表格内容自动计算_施工测绘20套测量自动计算表格,无脑输入数据出结果...
  6. php 5.5.1,PHP5.3.1 不再支持ISAPI
  7. form表单回车提交问题,JS监听回车事件
  8. Java——安全地停止线程
  9. Soft Value function基础和Soft Q Learning中Policy Improvement 证明
  10. BZOJ_1626_[Usaco2007_Dec]_Building_Roads_修建道路_(Kruskal)
  11. Linxu 输入子系统分析
  12. ubuntu 备份mysql数据库_Ubuntu Server下MySql数据库备份脚本代码
  13. mac m1 安装svn/subversion
  14. Linux无头浏览器的自动化测试实现
  15. 数字日期格式转换yyyymmdd_如何把日期改为yyyymmdd
  16. 图(3)——邻接链表法
  17. 使用 styled-components 定义组件样式
  18. layout-v21透明主题不生效的bug
  19. 我做的游戏终于上线了----三国Q传!!!
  20. 坠落的蚂蚁【思维/模拟】

热门文章

  1. 向日葵远程连接Ubuntu系统主机连接已中断解决方案
  2. flutter 九宫格菜单_flutter九宫格看图加强版
  3. 一文带你搞懂Go语言函数选项模式,Go函数一等公民。
  4. 丸子练练用户隐私保护协议
  5. 如何才能成为一个合格的项目负责人?
  6. GreenPlum版本升级
  7. 前端三大件--JavaScript详解
  8. performclick android,android performClick使用
  9. 有容乃大,无欲则刚,容是别人,欲是自己
  10. 柴天佑院士:自动化科学与技术发展方向