凝视是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凝视射线的更多相关文章

  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. 【php】使用gdb调试php程序

    1.简介 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.同时GDB也具有例如d ...

  2. jQuery Validate 表单验证插件----通过name属性来关联字段来验证,改变默认的提示信息,将校验规则写到 js 代码中

    一.下载依赖包 网盘下载:https://yunpan.cn/cryvgGGAQ3DSW  访问密码 f224 二. 添加一个另外一个插件jquery.validate.messages_cn.js. ...

  3. oracle 创建字段自增长——两种实现方式汇总

    mysql等其他数据库中有随着记录的插入而表ID自动增长的功能,而oracle却没有这样的功能,我们有以下两种方式可以解决字段自增长的功能. 因为两种方式都需要通过创建序列来实现,这里先给出序列的创建 ...

  4. FQ 也要使用 Telegram

    不知怎么回事,一款优秀的开源,跨平台,安全的即时通讯工具 Telegram 就被 GG 了. 但是我们还得继续使用--那就 FQ 吧.用 ShadowSocks FQ 还不错. 安装 ShadowSo ...

  5. Linux下Mysql安装

    1.下载安装包 首先查看Linux版本: [root@localhost ~]# lsb_release -a LSB Version: :core-4.0-amd64:core-4.0-noarch ...

  6. git 换行符LF与CRLF转换问题

    git 换行符LF与CRLF转换问题 一.背景 在各操作系统下,文本文件所使用的换行符是不一样的.UNIX/Linux 使用的是 0x0A(LF),早期的 Mac OS 使用的是0x0D(CR),后来 ...

  7. 三星嵌入式开发平台 三星Cortex-A9 4412 POP与SCP对比

    iTOP-4412核心板是迅为电子推出的一款高端四核核心板,其中分为POP封装与SCP封装,配备三星Exynos 4412四核处理器,主频为1.4GHz,内置16GB存储空间.该板设计小巧.配备三星自 ...

  8. 如何在TFS的过程模板中添加报表

    在新建团队项目的过程中,TFS的"新建团队项目向导"会根据用户选择的过程模板类型(CMMI, Scrum,Agile等)自动为团队项目创建一个SSRS(SQL Server Rep ...

  9. [麦先生]Laravel SQL语句记录方式

    打印sql语句,直接在你执行SQL语句后输出 方法一: $queries = DB::getQueryLog(); $a = end($queries); $tmp = str_replace('?' ...

  10. NOIP2010普及组T4 三国游戏——S.B.S.

    题目描述 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有 N 位武将(N为偶数且不小于 4),任意两个武将之 ...