Hololens入门之凝视

Hololens入门之凝视射线

凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象。然而在Unity中并没有明确的Gaze API或者组件。

概念上来说,Gaze是通过用户头部两眼之间发出一条向前方的射线来实现的,射线可以识别它所碰撞的物体。在Unity中,使用Main Camera来表示用户头部的位置和朝向。准确的说,是指UnityEngine.Camera.main.transform.forward 和 UnityEngine.Camera.main.transform.position.调用Physics.RayCast 发出射线后可以得到RaycastHit结果,该结果包含了碰撞点的3D位置参数和碰撞对象。


实现Gaze的示例:

可以直接使用HoloToolkit中的GazeManager.cs脚本来实现凝视射线。 关于HoloToolKit的使用,本文不再做描述,可以参考上一篇文章。

1、添加GazeManager.cs

点击“ Create Empty” 创建一个空游戏对象,并将其命名为 Manager,为 Manager对象添加核心脚本组件GazeManager.cs

// 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; }

        /// <summary>
        /// Object currently being focused on.
        /// </summary>
        public GameObject FocusedObject { 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 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>
        /// Adds the stabilization plane modifier if it's enabled and if it doesn't exist yet.
        /// </summary>
        private void UpdateStabilizationPlane()
        {
            // We want to use the stabilization logic.
            if (SetStabilizationPlane)
            {
                // Check if it exists in the scene.
                if (StabilizationPlaneModifier.Instance == null)
                {
                    // If not, add it to us.
                    gameObject.AddComponent<StabilizationPlaneModifier>();
                }
            }

            if (StabilizationPlaneModifier.Instance)
            {
                StabilizationPlaneModifier.Instance.SetStabilizationPlane = SetStabilizationPlane;
            }
        }
    }
}


2、创建一个新的游戏对象Cube,用来测试凝视效果


3、添加Cursor

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

从 HoloToolkit/Input/Prefabs/ 目录下拖拽 Cursor Prefab 组件到场景中。这样当凝视在全息对象时,其表面会出现一个蓝色的光圈,表示当前凝视该对象,当射线离开该游戏对象时,Cursor变成一个点光源,以此来区分是否凝视游戏对象。

可以查看到Cursor中存在两个光标对象,分别是凝视在对象上及离开光息对象时分别显示的光标


CursorManager.cs

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using HoloToolkit.Unity;
using UnityEngine;

/// <summary>
/// CursorManager class takes Cursor GameObjects.
/// One that is on Holograms and another off Holograms.
/// 1. Shows the appropriate Cursor when a Hologram is hit.
/// 2. Places the appropriate Cursor at the hit position.
/// 3. Matches the Cursor normal to the hit surface.
/// </summary>
public partial class CursorManager : Singleton<CursorManager>
{
    //凝视射线在全息对象上时显示的光标对象
    [Tooltip("Drag the Cursor object to show when it hits a hologram.")]
    public GameObject CursorOnHolograms;
    //凝视射线离开全息对象时显示的光标对象
    [Tooltip("Drag the Cursor object to show when it does not hit a hologram.")]
    public GameObject CursorOffHolograms;

    [Tooltip("Distance, in meters, to offset the cursor from the collision point.")]
    public float DistanceFromCollision = 0.01f;

    void Awake()
    {
        //当未设定光标对象时直接返回
        if (CursorOnHolograms == null || CursorOffHolograms == null)
        {
            return;
        }
        
        // Hide the Cursors to begin with.
        CursorOnHolograms.SetActive(false);
        CursorOffHolograms.SetActive(false);
    }

    void LateUpdate()
    {
        if (GazeManager.Instance == null || CursorOnHolograms == null || CursorOffHolograms == null)
        {
            return;
        }
        //当凝视射线在全息对象上及离开全息对象时,分别显示不同的光标对象,以此来进行区分
        if (GazeManager.Instance.Hit)
        {
            CursorOnHolograms.SetActive(true);
            CursorOffHolograms.SetActive(false);
        }
        else
        {
            CursorOffHolograms.SetActive(true);
            CursorOnHolograms.SetActive(false);
        }

        //计算并安置光标
        // Place the cursor at the calculated position.
        this.gameObject.transform.position = GazeManager.Instance.Position + GazeManager.Instance.Normal * DistanceFromCollision;

        // Orient the cursor to match the surface being gazed at.
        gameObject.transform.up = GazeManager.Instance.Normal;
    }
}

4、运行测试

当凝视射线在Cube上时,出现蓝色的光圈,表示当前凝视的点在该位置



当凝视射线离开Cube时,光标显示为一个点光源



  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Hololens2开发入门精要PDF是一本简单直观、易于理解的教程,旨在为初学者提供一套完整的从入门到精通Hololens2开发的基础知识。该教程包括了Hololens2基础知识、开发环境搭建、应用程序设计和开发、交互设计等内容,旨在帮助读者从零基础开始快速上手。 首先,该PDF详细介绍了Hololens2的软硬件结构,包括用于显示、定位、跟踪、输入和音频等功能的各种传感器和硬件设备。同时该文还详细介绍了Windows Mixed Reality和Visual Studio集成开发环境的搭建方法,为读者提供了一个高效的开发环境。 其次,该教程以实际应用程序开发为主线,从设计思路到具体实现,详细地讲解了如何使用Hololens2的API来完成图像展示、交互、跟踪等功能。读者可以通过该部分学会如何使用Unity3D、C#语言进行Hololens2应用程序的开发。此外,该部分还包括了场景的搭建、动画的制作和应用、声音的处理等方面的内容。 最后,该PDF还介绍了Hololens2的用户交互设计原则,包括采用自然、直观、无干扰的交互方式、足够反馈和控制、信息分层传递等原则。这将帮助读者在应用程序开发过程中更好地设计用户界面和交互方式,提高用户的体验。 总而言之,该PDF涵盖了Hololens2开发的基本知识和技能,对于新手来说是一个很好的指南。通过学习这本教程,读者可以掌握从开发环境搭建到应用程序开发的全流程,为日后深入开发奠定良好的基础。 ### 回答2: Hololens2开发入门精要pdf是一本非常有价值的书籍,它提供了一系列的教程和实践,帮助开发者快速入门Hololens2的开发。该书的内容包括Hololens2的硬件和软件特性的介绍、如何搭建开发环境、如何构建Hololens2应用程序、如何使用空间映射、手势控制、语音识别和眼动追踪等技术,并提供了实例来展示如何应用这些技术。 该书的作者通过生动详实的案例,以一种非常易于理解和跟随的方式,帮助开发者掌握Hololens2开发所需的关键技能。其中,作者详细讲解了如何构建和查看Hololens2应用程序中的空间映射,介绍了如何使用手势和语音命令控制应用程序功能,如何充分利用和应用Hololens2的功能等等。 此外,该书还提供了多个练习项目,帮助读者在实践过程中逐渐掌握Hololens2的开发技巧。这些实践题目包括创建独立程序、使用Unity创建交互式环境、应用语音、眼动追踪和手势等技术等。 总之,Hololens2开发入门精要pdf是一本非常实用的书籍,对Hololens2开发者具有非常重要和广泛的意义。它不仅能够帮助开发者快速掌握Hololens2的开发技术,还能够司机开发者更深入的了解Hololens2的特色和优点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值