HoloLens开发手记 - Unity之Gaze凝视射线
凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象。然而在Unity中并没有明确的Gaze API或者组件。
实现Gaze Implementing Gaze
概念上来说,Gaze是通过用户头部两眼之间发出一条向前方的射线来实现的,射线可以识别它所碰撞的物体。在Unity中,使用Main Camera来表示用户头部的位置和朝向。准确的说,是指 UnityEngine.Camera.main.transform.forward 和 UnityEngine.Camera.main.transform.position.
调用 Physics.RayCast 发出射线后可以得到 RaycastHit 结果,该结果包含了碰撞点的3D位置参数和碰撞对象。
实现Gaze的例子
- void Update()
- {
- RaycastHit hitInfo;
- if (Physics.Raycast(
- Camera.main.transform.position,
- Camera.main.transform.forward,
- out hitInfo,
- 20.0f,
- Physics.DefaultRaycastLayers))
- {
- // 如果射线成功击中物体
- // hitInfo.point代表了射线碰撞的位置
- // hitInfo.collider.gameObject代表了射线注视的全息对象
- }
- }
最佳做法
在使用Gaze的时候,尽量避免每个物体都发出凝视射线,而是使用单例对象来管理凝视射线和其结果。
可视化凝视 Visualizing Gaze
就像PC使用鼠标来选中和交互图标一样,你可以为凝视也实现一个指针来更好的代表用户的凝视。
可视化凝视的例子
可以参考或直接使用HoloToolkit-Unity项目中的GazeManager.cs和预制的各种指针资源,包括Cursor.prefab 和 CursorWithFeedback.prefab 等。
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // Licensed under the MIT License. See LICENSE in the project root for license information.
- using UnityEngine;
- using UnityEngine.VR.WSA;
- namespace HoloToolkit.Unity
- {
- /// <summary>
- /// GazeManager determines the location of the user's gaze, hit position and normals.
- /// </summary>
- public partial class GazeManager : Singleton<GazeManager>
- {
- [Tooltip("Maximum gaze distance, in meters, for calculating a hit.")]
- public float MaxGazeDistance = 15.0f;
- [Tooltip("Select the layers raycast should target.")]
- public LayerMask RaycastLayerMask = Physics.DefaultRaycastLayers;
- /// <summary>
- /// Physics.Raycast result is true if it hits a hologram.
- /// </summary>
- public bool Hit { get; private set; }
- /// <summary>
- /// HitInfo property gives access
- /// to RaycastHit public members.
- /// </summary>
- public RaycastHit HitInfo { get; private set; }
- /// <summary>
- /// Position of the intersection of the user's gaze and the holograms in the scene.
- /// </summary>
- public Vector3 Position { get; private set; }
- /// <summary>
- /// RaycastHit Normal direction.
- /// </summary>
- public Vector3 Normal { get; private set; }
- [Tooltip("Checking enables SetFocusPointForFrame to set the stabilization plane.")]
- public bool SetStabilizationPlane = true;
- [Tooltip("Lerp speed when moving focus point closer.")]
- public float LerpStabilizationPlanePowerCloser = 4.0f;
- [Tooltip("Lerp speed when moving focus point farther away.")]
- public float LerpStabilizationPlanePowerFarther = 7.0f;
- private Vector3 gazeOrigin;
- private Vector3 gazeDirection;
- private float lastHitDistance = 15.0f;
- private GameObject focusedObject;
- private void Update()
- {
- gazeOrigin = Camera.main.transform.position;
- gazeDirection = Camera.main.transform.forward;
- UpdateRaycast();
- UpdateStabilizationPlane();
- }
- /// <summary>
- /// Calculates the Raycast hit position and normal.
- /// </summary>
- private void UpdateRaycast()
- {
- // Get the raycast hit information from Unity's physics system.
- RaycastHit hitInfo;
- Hit = Physics.Raycast(gazeOrigin,
- gazeDirection,
- out hitInfo,
- MaxGazeDistance,
- RaycastLayerMask);
- GameObject oldFocusedObject = focusedObject;
- // Update the HitInfo property so other classes can use this hit information.
- HitInfo = hitInfo;
- if (Hit)
- {
- // If the raycast hits a hologram, set the position and normal to match the intersection point.
- Position = hitInfo.point;
- Normal = hitInfo.normal;
- lastHitDistance = hitInfo.distance;
- focusedObject = hitInfo.collider.gameObject;
- }
- else
- {
- // If the raycast does not hit a hologram, default the position to last hit distance in front of the user,
- // and the normal to face the user.
- Position = gazeOrigin + (gazeDirection * lastHitDistance);
- Normal = gazeDirection;
- focusedObject = null;
- }
- // Check if the currently hit object has changed
- if (oldFocusedObject != focusedObject)
- {
- if (oldFocusedObject != null)
- {
- oldFocusedObject.SendMessage("OnGazeLeave", SendMessageOptions.DontRequireReceiver);
- }
- if (focusedObject != null)
- {
- focusedObject.SendMessage("OnGazeEnter", SendMessageOptions.DontRequireReceiver);
- }
- }
- }
- /// <summary>
- /// Updates the focus point for every frame.
- /// </summary>
- private void UpdateStabilizationPlane()
- {
- if (SetStabilizationPlane)
- {
- // Calculate the delta between camera's position and current hit position.
- float focusPointDistance = (gazeOrigin - Position).magnitude;
- float lerpPower = focusPointDistance > lastHitDistance
- ? LerpStabilizationPlanePowerFarther
- : LerpStabilizationPlanePowerCloser;
- // Smoothly move the focus point from previous hit position to new position.
- lastHitDistance = Mathf.Lerp(lastHitDistance, focusPointDistance, lerpPower * Time.deltaTime);
- Vector3 newFocusPointPosition = gazeOrigin + (gazeDirection * lastHitDistance);
- HolographicSettings.SetFocusPointForFrame(newFocusPointPosition, -gazeDirection);
- }
- }
- }
- }
HoloLens开发手记 - Unity之Gaze凝视射线的更多相关文章
- HoloLens开发手记 - Unity development overview 使用Unity开发概述
Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...
- HoloLens开发手记 - Unity之Gestures手势识别
手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层API,可以满足不同的手势定制需求.底层API能够获取手的位置和速度信息,高层API则借助手势识别器来识别预设的 ...
- HoloLens开发手记 - Unity之摄像头篇
当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...
- HoloLens开发手记 - Unity之Spatial mapping 空间映射
本文主要讨论如何在Unity项目中集成空间映射功能.Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者: HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使 ...
- HoloLens开发手记 - Unity之Recommended settings 推荐设置
Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...
- HoloLens开发手记 - Unity之Tracking loss
当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...
- HoloLens开发手记 - Unity之语音输入
对于HoloLens,语音输入是三大基本输入方式之一,广泛地运用在各种交互中.HoloLens上语音输入有三种形式,分别是: 语音命令 Voice Command 听写 Diction 语法识别 Gr ...
- HoloLens开发手记 - Unity之Persistence 场景保持
Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...
- HoloLens开发手记 - Unity之Spatial Sounds 空间声音
本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...
随机推荐
- C#照片批量压缩小工具
做了一个照片批量压缩工具,其实核心代码几分钟就完成了,但整个小工具做下来还是花了一天的时间.中间遇到了大堆问题,并寻求最好的解决方案予以解决.现在就分享一下这个看似简单的小工具所使用的技术. 软件界面 ...
- OSX下VirtualBox安装CentOS
1.OSX上下载安装VirtualBox 2.新建虚拟机(所有选项默认即可) 3.启动虚拟机,选择CentOS安装镜像 CentOS-6.7-x86_64-minimal.iso 此处下载的是最小镜像 ...
- AngularJS的一点学习笔记
ng-options="item.action for item in todos" ng-options表达式的基本形式, 形如 "<标签> for < ...
- JS键盘事件监听
window.onload=function(){ var keyword = document.getElementById("keyword"); keyword.onkeyu ...
- java帮助文档下载
JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载JDK(Java Development Kit,Java开发包,Java开发工具)是一个写Java的applet和 ...
- 边工作边刷题:70天一遍leetcode: day 81-1
Alien Dictionary 要点:topological sort,bfs 只有前后两个word之间构成联系,一个word里的c是没有关系的 只要得到两个word第一个不同char之间的part ...
- HDU 4460 Friend Chains --BFS
题意:问给定的一张图中,相距最远的两个点的距离为多少.解法:跟求树的直径差不多,从1 开始bfs,得到一个最远的点,然后再从该点bfs一遍,得到的最长距离即为答案. 代码: #include < ...
- Tarjian算法求强联通分量
如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.强连通图有向图的极大强连通子图,称为强连通分量(strong ...
- java14-9 Doteformat的练习
需求: 键盘录入出生年月日,计算出距离现在已经生活了几天 分析: A:创建键盘录入固定模式的字符串 B:计算步骤: a:把输入进来的字符串格式化成日期 b:获取现在的日期,减去格式化后的日期 c:把得 ...
- UITableViewCell动态AutoLayout布局
相关链接: 使用Autolayout实现UITableView的Cell动态布局和高度动态改变 IOS tableView cell动态高度 (autoLayout) AutoLayoutClub 使 ...