凝视是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的例子

  1. void Update()
  2. {
  3. RaycastHit hitInfo;
  4. if (Physics.Raycast(
  5. Camera.main.transform.position,
  6. Camera.main.transform.forward,
  7. out hitInfo,
  8. 20.0f,
  9. Physics.DefaultRaycastLayers))
  10. {
  11. // 如果射线成功击中物体
  12. // hitInfo.point代表了射线碰撞的位置
  13. // hitInfo.collider.gameObject代表了射线注视的全息对象
  14. }
  15. }

最佳做法

在使用Gaze的时候,尽量避免每个物体都发出凝视射线,而是使用单例对象来管理凝视射线和其结果。

可视化凝视 Visualizing Gaze


就像PC使用鼠标来选中和交互图标一样,你可以为凝视也实现一个指针来更好的代表用户的凝视。

可视化凝视的例子

可以参考或直接使用HoloToolkit-Unity项目中的GazeManager.cs和预制的各种指针资源,包括Cursor.prefab 和 CursorWithFeedback.prefab 等。

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3.  
  4. using UnityEngine;
  5. using UnityEngine.VR.WSA;
  6.  
  7. namespace HoloToolkit.Unity
  8. {
  9. /// <summary>
  10. /// GazeManager determines the location of the user's gaze, hit position and normals.
  11. /// </summary>
  12. public partial class GazeManager : Singleton<GazeManager>
  13. {
  14. [Tooltip("Maximum gaze distance, in meters, for calculating a hit.")]
  15. public float MaxGazeDistance = 15.0f;
  16.  
  17. [Tooltip("Select the layers raycast should target.")]
  18. public LayerMask RaycastLayerMask = Physics.DefaultRaycastLayers;
  19.  
  20. /// <summary>
  21. /// Physics.Raycast result is true if it hits a hologram.
  22. /// </summary>
  23. public bool Hit { get; private set; }
  24.  
  25. /// <summary>
  26. /// HitInfo property gives access
  27. /// to RaycastHit public members.
  28. /// </summary>
  29. public RaycastHit HitInfo { get; private set; }
  30.  
  31. /// <summary>
  32. /// Position of the intersection of the user's gaze and the holograms in the scene.
  33. /// </summary>
  34. public Vector3 Position { get; private set; }
  35.  
  36. /// <summary>
  37. /// RaycastHit Normal direction.
  38. /// </summary>
  39. public Vector3 Normal { get; private set; }
  40.  
  41. [Tooltip("Checking enables SetFocusPointForFrame to set the stabilization plane.")]
  42. public bool SetStabilizationPlane = true;
  43. [Tooltip("Lerp speed when moving focus point closer.")]
  44. public float LerpStabilizationPlanePowerCloser = 4.0f;
  45. [Tooltip("Lerp speed when moving focus point farther away.")]
  46. public float LerpStabilizationPlanePowerFarther = 7.0f;
  47.  
  48. private Vector3 gazeOrigin;
  49. private Vector3 gazeDirection;
  50. private float lastHitDistance = 15.0f;
  51. private GameObject focusedObject;
  52.  
  53. private void Update()
  54. {
  55. gazeOrigin = Camera.main.transform.position;
  56. gazeDirection = Camera.main.transform.forward;
  57.  
  58. UpdateRaycast();
  59.  
  60. UpdateStabilizationPlane();
  61. }
  62.  
  63. /// <summary>
  64. /// Calculates the Raycast hit position and normal.
  65. /// </summary>
  66. private void UpdateRaycast()
  67. {
  68. // Get the raycast hit information from Unity's physics system.
  69. RaycastHit hitInfo;
  70. Hit = Physics.Raycast(gazeOrigin,
  71. gazeDirection,
  72. out hitInfo,
  73. MaxGazeDistance,
  74. RaycastLayerMask);
  75.  
  76. GameObject oldFocusedObject = focusedObject;
  77. // Update the HitInfo property so other classes can use this hit information.
  78. HitInfo = hitInfo;
  79.  
  80. if (Hit)
  81. {
  82. // If the raycast hits a hologram, set the position and normal to match the intersection point.
  83. Position = hitInfo.point;
  84. Normal = hitInfo.normal;
  85. lastHitDistance = hitInfo.distance;
  86. focusedObject = hitInfo.collider.gameObject;
  87. }
  88. else
  89. {
  90. // If the raycast does not hit a hologram, default the position to last hit distance in front of the user,
  91. // and the normal to face the user.
  92. Position = gazeOrigin + (gazeDirection * lastHitDistance);
  93. Normal = gazeDirection;
  94. focusedObject = null;
  95. }
  96.  
  97. // Check if the currently hit object has changed
  98. if (oldFocusedObject != focusedObject)
  99. {
  100. if (oldFocusedObject != null)
  101. {
  102. oldFocusedObject.SendMessage("OnGazeLeave", SendMessageOptions.DontRequireReceiver);
  103. }
  104. if (focusedObject != null)
  105. {
  106. focusedObject.SendMessage("OnGazeEnter", SendMessageOptions.DontRequireReceiver);
  107. }
  108. }
  109. }
  110.  
  111. /// <summary>
  112. /// Updates the focus point for every frame.
  113. /// </summary>
  114. private void UpdateStabilizationPlane()
  115. {
  116. if (SetStabilizationPlane)
  117. {
  118. // Calculate the delta between camera's position and current hit position.
  119. float focusPointDistance = (gazeOrigin - Position).magnitude;
  120. float lerpPower = focusPointDistance > lastHitDistance
  121. ? LerpStabilizationPlanePowerFarther
  122. : LerpStabilizationPlanePowerCloser;
  123.  
  124. // Smoothly move the focus point from previous hit position to new position.
  125. lastHitDistance = Mathf.Lerp(lastHitDistance, focusPointDistance, lerpPower * Time.deltaTime);
  126.  
  127. Vector3 newFocusPointPosition = gazeOrigin + (gazeDirection * lastHitDistance);
  128.  
  129. HolographicSettings.SetFocusPointForFrame(newFocusPointPosition, -gazeDirection);
  130. }
  131. }
  132. }
  133. }

HoloLens开发手记 - Unity之Gaze凝视射线的更多相关文章

  1. HoloLens开发手记 - Unity development overview 使用Unity开发概述

    Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...

  2. HoloLens开发手记 - Unity之Gestures手势识别

    手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层API,可以满足不同的手势定制需求.底层API能够获取手的位置和速度信息,高层API则借助手势识别器来识别预设的 ...

  3. HoloLens开发手记 - Unity之摄像头篇

    当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...

  4. HoloLens开发手记 - Unity之Spatial mapping 空间映射

    本文主要讨论如何在Unity项目中集成空间映射功能.Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者: HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使 ...

  5. HoloLens开发手记 - Unity之Recommended settings 推荐设置

    Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...

  6. HoloLens开发手记 - Unity之Tracking loss

    当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...

  7. HoloLens开发手记 - Unity之语音输入

    对于HoloLens,语音输入是三大基本输入方式之一,广泛地运用在各种交互中.HoloLens上语音输入有三种形式,分别是: 语音命令 Voice Command 听写 Diction 语法识别 Gr ...

  8. HoloLens开发手记 - Unity之Persistence 场景保持

    Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...

  9. HoloLens开发手记 - Unity之Spatial Sounds 空间声音

    本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...

随机推荐

  1. C#照片批量压缩小工具

    做了一个照片批量压缩工具,其实核心代码几分钟就完成了,但整个小工具做下来还是花了一天的时间.中间遇到了大堆问题,并寻求最好的解决方案予以解决.现在就分享一下这个看似简单的小工具所使用的技术. 软件界面 ...

  2. OSX下VirtualBox安装CentOS

    1.OSX上下载安装VirtualBox 2.新建虚拟机(所有选项默认即可) 3.启动虚拟机,选择CentOS安装镜像 CentOS-6.7-x86_64-minimal.iso 此处下载的是最小镜像 ...

  3. AngularJS的一点学习笔记

    ng-options="item.action for item in todos" ng-options表达式的基本形式, 形如 "<标签> for < ...

  4. JS键盘事件监听

    window.onload=function(){ var keyword = document.getElementById("keyword"); keyword.onkeyu ...

  5. java帮助文档下载

    JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载JDK(Java Development Kit,Java开发包,Java开发工具)是一个写Java的applet和 ...

  6. 边工作边刷题:70天一遍leetcode: day 81-1

    Alien Dictionary 要点:topological sort,bfs 只有前后两个word之间构成联系,一个word里的c是没有关系的 只要得到两个word第一个不同char之间的part ...

  7. HDU 4460 Friend Chains --BFS

    题意:问给定的一张图中,相距最远的两个点的距离为多少.解法:跟求树的直径差不多,从1 开始bfs,得到一个最远的点,然后再从该点bfs一遍,得到的最长距离即为答案. 代码: #include < ...

  8. Tarjian算法求强联通分量

    如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.强连通图有向图的极大强连通子图,称为强连通分量(strong ...

  9. java14-9 Doteformat的练习

    需求: 键盘录入出生年月日,计算出距离现在已经生活了几天 分析: A:创建键盘录入固定模式的字符串 B:计算步骤: a:把输入进来的字符串格式化成日期 b:获取现在的日期,减去格式化后的日期 c:把得 ...

  10. UITableViewCell动态AutoLayout布局

    相关链接: 使用Autolayout实现UITableView的Cell动态布局和高度动态改变 IOS tableView cell动态高度 (autoLayout) AutoLayoutClub 使 ...