Unity 工具类 之 AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存

2024-02-23 04:50

本文主要是介绍Unity 工具类 之 AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Unity 工具类 之 AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存

目录

Unity 工具类 之 AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存

一、引出问题

二、解决方法

三、注意事项

四、效果预览

五、实现步骤

六、附加

鼠标右键交互功能

取消掉UGUI系统默认的鼠标点击交互功能


 

一、引出问题

Unity在使用中,AR和VR开发中,会遇到以下问题

  • 1、首先需要分屏,一般左右两屏幕;

  • 2、交互上一般的点击,由于屏幕的原因(不像手机一样的触击屏幕交互),就不适合点击交互了;

  • 3、Gaze 凝视 交互就应运而生;

  • 4、但是在电脑上开发中,Gaze 交互操作又不是很方便,所以用需要用到 点击交互;

故综上所述,Gaze 凝视交互和点击交互需要并存。

二、解决方法

1、左右两个camera,分别渲染,实现分屏;

2、Canvas 设置为 worldSpace,然后交互camera 设置为 RightCamera(当然根据需要切换也可以);

3、GazeEyeRaycaster 实现 Gaze 交互,且不干扰点击 UI 事件;

三、注意事项

1、由于分屏,所以凝视点点不能像之前单屏一样为屏幕的中心,而是左右屏中某个屏的中心( ScreenWidth * 3/4,ScreenHeight * 1/2(右屏幕中心) 或者 ScreenWidth * 1/4,ScreenHeight * 1/2 (左屏幕中心))

2、这里点击交互以右屏camera交互为主(也可以根据需要动态修改);

四、效果预览

五、实现步骤

1、打开Unity,新建场景,布局如下

2、主要脚本

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections.Generic;
#if UNITY_2017_2_OR_NEWER
using UnityEngine.XR;
#else
using XRSettings = UnityEngine.VR.VRSettings;
#endif[System.Serializable]
public class FloatUnityEvent : UnityEvent<float> { }public class GazeEyeRaycaster : MonoBehaviour
{[SerializeField, Tooltip("In seconds")]float m_loadingTime;[SerializeField]FloatUnityEvent m_onLoad;float m_elapsedTime = 0;// Prevents loop over the same selectableSelectable m_excluded; Selectable m_currentSelectable;RaycastResult m_currentRaycastResult;IPointerClickHandler m_clickHandler;IDragHandler m_dragHandler;EventSystem m_eventSystem;PointerEventData m_pointerEvent;private void Start(){m_eventSystem = EventSystem.current;m_pointerEvent = new PointerEventData(m_eventSystem);m_pointerEvent.button = PointerEventData.InputButton.Left;}void Update(){// 因为要分屏所以让 m_pointerEvent.position 在右边屏幕中心(即为 width * 3/4,height * 1/2)// Set pointer positionm_pointerEvent.position =
#if UNITY_EDITORnew Vector2(Screen.width * 3 / 4, Screen.height / 2);
#elsenew Vector2(XRSettings.eyeTextureWidth * 3 / 4, XRSettings.eyeTextureHeight / 2);
#endifList<RaycastResult> raycastResults = new List<RaycastResult>();m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);// Detect selectableif (raycastResults.Count > 0){foreach(var result in raycastResults){var newSelectable = result.gameObject.GetComponentInParent<Selectable>();if (newSelectable){if(newSelectable != m_excluded && newSelectable != m_currentSelectable){Select(newSelectable);m_currentRaycastResult = result;}break;}}}else{if(m_currentSelectable || m_excluded){Select(null, null);}}// Target is being activatingif (m_currentSelectable){m_elapsedTime += Time.deltaTime;m_onLoad.Invoke(m_elapsedTime / m_loadingTime);if (m_elapsedTime > m_loadingTime){if (m_clickHandler != null){m_clickHandler.OnPointerClick(m_pointerEvent);Select(null, m_currentSelectable);}else if (m_dragHandler != null){m_pointerEvent.pointerPressRaycast = m_currentRaycastResult;m_dragHandler.OnDrag(m_pointerEvent);}}}}void Select(Selectable s, Selectable exclude = null){m_excluded = exclude;if (m_currentSelectable)m_currentSelectable.OnPointerExit(m_pointerEvent);m_currentSelectable = s;if (m_currentSelectable){m_currentSelectable.OnPointerEnter(m_pointerEvent);m_clickHandler = m_currentSelectable.GetComponent<IPointerClickHandler>();m_dragHandler = m_currentSelectable.GetComponent<IDragHandler>();}m_elapsedTime = 0;m_onLoad.Invoke(m_elapsedTime / m_loadingTime);}
}

3、运行场景效果

4、工程场景下载

UnityGazeAndClickUI AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存 点击下载

六、附加

鼠标右键交互功能

1、该脚本保留之前的凝视计时确认操作,同事添加凝视点击交互,具体见脚本

public class GazeEyeRaycasterAndInteraactiveType : MonoBehaviour{public enum InterActiveType { None,   //   无交互TimeCounter,    // 计时交互LeftClick,      // 右键点击}[SerializeField, Tooltip("In seconds")]float m_loadingTime;[SerializeField]FloatUnityEvent m_onLoad;[SerializeField]InterActiveType mCurInterActiveType = InterActiveType.LeftClick;float m_elapsedTime = 0;// Prevents loop over the same selectableSelectable m_excluded;Selectable m_currentSelectable;RaycastResult m_currentRaycastResult;IPointerClickHandler m_clickHandler;IDragHandler m_dragHandler;EventSystem m_eventSystem;PointerEventData m_pointerEvent;private void Start(){m_eventSystem = EventSystem.current;m_pointerEvent = new PointerEventData(m_eventSystem);m_pointerEvent.button = PointerEventData.InputButton.Left;}void Update(){// 因为要分屏所以让 m_pointerEvent.position 在右边屏幕中心(即为 width * 3/4,height * 1/2)// Set pointer positionm_pointerEvent.position =
#if UNITY_EDITORnew Vector2(Screen.width * 3 / 4, Screen.height / 2);
#elsenew Vector2(XRSettings.eyeTextureWidth * 3 / 4, XRSettings.eyeTextureHeight / 2);
#endifList<RaycastResult> raycastResults = new List<RaycastResult>();m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);// Detect selectableif (raycastResults.Count > 0){foreach (var result in raycastResults){var newSelectable = result.gameObject.GetComponentInParent<Selectable>();if (newSelectable){if (newSelectable != m_excluded && newSelectable != m_currentSelectable){Select(newSelectable);m_currentRaycastResult = result;}break;}}}else{if (m_currentSelectable || m_excluded){Select(null, null);}}// Target is being activatingif (m_currentSelectable){InteractiveHandle(mCurInterActiveType);}}void InteractiveHandle(InterActiveType interActiveType) {if (interActiveType == InterActiveType.TimeCounter){m_elapsedTime += Time.deltaTime;m_onLoad.Invoke(m_elapsedTime / m_loadingTime);if (m_elapsedTime > m_loadingTime){ClickAndDragUIHandle();}}else if (interActiveType == InterActiveType.LeftClick){if (Input.GetMouseButton(0)){ClickAndDragUIHandle();}}}void ClickAndDragUIHandle() {if (m_clickHandler != null){m_clickHandler.OnPointerClick(m_pointerEvent);Select(null, m_currentSelectable);}else if (m_dragHandler != null){m_pointerEvent.pointerPressRaycast = m_currentRaycastResult;m_dragHandler.OnDrag(m_pointerEvent);}}void Select(Selectable s, Selectable exclude = null){m_excluded = exclude;if (m_currentSelectable)m_currentSelectable.OnPointerExit(m_pointerEvent);m_currentSelectable = s;if (m_currentSelectable){m_currentSelectable.OnPointerEnter(m_pointerEvent);m_clickHandler = m_currentSelectable.GetComponent<IPointerClickHandler>();m_dragHandler = m_currentSelectable.GetComponent<IDragHandler>();}m_elapsedTime = 0;m_onLoad.Invoke(m_elapsedTime / m_loadingTime);}}

取消掉UGUI系统默认的鼠标点击交互功能

 

这篇关于Unity 工具类 之 AR/VR 分屏 Gaze 凝视 和 Click 点击 UI 交互并存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/737568

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

10个好用的AI写作工具【亲测免费】

1. 光速写作 传送入口:http://u3v.cn/6hXWYa AI打工神器,一键生成文章&ppt 2. 讯飞写作 传送入口:http://m6z.cn/5ODiSw 3. 讯飞绘文 传送入口:https://turbodesk.xfyun.cn/?channelid=gj3 4. AI排版助手 传送入口:http://m6z.cn/6ppnPn 5. Kim

C# 防止按钮botton重复“点击”的方法

在使用C#的按钮控件的时候,经常我们想如果出现了多次点击的时候只让其在执行的时候只响应一次。这个时候很多人可能会想到使用Enable=false, 但是实际情况是还是会被多次触发,因为C#采用的是消息队列机制,这个时候我们只需要在Enable = true 之前加一句 Application.DoEvents();就能达到防止重复点击的问题。 private void btnGenerateSh