Hololens官方教程精简版 - 04. Gesture(手势)
Posted PhiloChou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hololens官方教程精简版 - 04. Gesture(手势)相关的知识,希望对你有一定的参考价值。
前言
注意:本文已更新到5.5.1f1版本
个人建议,学习Holograms 211之前,一定完成《Hololens官方教程精简版 - 02. Introduction with Device》的学习。
本篇集中学习手势功能,完成以下目标:
- 是否已检测到手势动作
- 使用导航手势来旋转物体
- 手势超出检测区域的处理
- 手势移动物体
Unity Setup
请按照第一篇的教程,完成项目的创建。
新建文件夹:”Assets/_Scenes/Holograms 211/”
新建场景:”Assets/_Scenes/Holograms 211/Holograms 211.unity”
打开场景,删除默认的Main Camera
将”Assets/HoloToolkit/Input/Prefabs/HololensCamera.prefab”添加到Hierarchy根级
添加一个Cube,按如下属性进行设置:
本节完成,测试运行!
Chapter 1 - Hand detected feedback
目标
检测到手势后,光标发生变化
实践
在Project面板中,找到”Assets/HoloToolkit/Input/Prefabs/InputManager.prefab”,拖动到Hierarchy根目录
同样,将”Assets/HoloToolkit/Input/Prefabs/Cursor/CursorWithFeedback.prefab”,拖动到Hierarchy根目录
本节完成!
在编辑器中进行测试,点击Play,在Game窗口中,按住空格键模拟右手手势,会发现光标发生了变化。
在Hololens模拟器或者真机上测试,会产生同样的效果。
说明
HoloToolkit内置的几个光标,都继承自Cursor抽象类,如图:
而Cursor内部的实现,简单来说,就是当输入源事件触发时(比如检测到手势),修改光标的状态值(一个枚举值CursorStateEnum)。
在Update的UpdateCursorState()方法调用时,根据这个光标状态值,进行相应的光标变化处理。这个处理,
实际上,执行的是一个虚函数:
public virtual void OnCursorStateChange(CursorStateEnum state)
具体的光标类重写Override这个方法,实现光标变化的细节。
比如本节所使用的光标CursorWithFeedback.prefab,调用的是ObjectCursor类,相关代码为:
public class ObjectCursor : Cursor
...
public override void OnCursorStateChange(CursorStateEnum state)
base.OnCursorStateChange(state);
if (state != CursorStateEnum.Contextual)
// Hide all children first
for(int i = 0; i < ParentTransform.childCount; i++)
ParentTransform.GetChild(i).gameObject.SetActive(false);
// Set active any that match the current state
for (int i = 0; i < CursorStateData.Length; i++)
if (CursorStateData[i].CursorState == state)
CursorStateData[i].CursorObject.SetActive(true);
注意:5.5.1f1代码有些变化,但思路一致
同时,HoloToolkit还提供了其他几个光标类供我们使用,分别为:
- ObjectCursor
- SpriteCursor
- MeshCursor
- AnimatedCursor
如果想扩展我们自己的光标,可以继承上面的类,或者直接继承Cursor类。
由于本系列是精简版,所以不赘述,后面有精力会补充深入版本的教程。
Chapter 2 - Navigation
目标
使用导航手势,旋转Cube
实践
新建文件夹:”Assets/_Scenes/Holograms 211/Scripts/”
新建脚本文件:”Assets/_Scenes/Holograms 211/Scripts/Cube211.cs”,将其拖拽到 Cube 上 ,编写脚本如下:
using HoloToolkit.Unity.InputModule;
using UnityEngine;
public class Cube211 : MonoBehaviour, INavigationHandler
[Tooltip("旋转速度")]
public float RotationSensitivity = 10.0f;
public void OnNavigationCanceled(NavigationEventData eventData)
//do nothing
public void OnNavigationCompleted(NavigationEventData eventData)
//do nothing
public void OnNavigationStarted(NavigationEventData eventData)
//do nothing
public void OnNavigationUpdated(NavigationEventData eventData)
// 计算旋转值,其中:eventData的CumulativeDelta返回手势导航差值,值域[-1, 1]
float rotationFactor = eventData.CumulativeDelta.x * RotationSensitivity;
transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
本节结束!
使用模拟器或者真机进行测试,凝视Cube,用手势进行横向拖拽,会发现Cube发生旋转。
说明
- INavigationHandler
手势导航事件处理接口,该事件会将导航差值(归一化)传递出来给开发者使用,取值在[-1, 1]之间。
Chapter 3 - Hand Guidance
目标
当手势快要超出检测范围时,给出提示
实践
- 在Hierarchy根级新建空对象,并重命名为:Controller
- 在Project中查找HandGuidance脚本,拖拽到Controller上
- 点击Controller,显示Inspector面板
- 将Hierarchy的CursorWithFeedback对象拖拽到Cursor属性上。
- 点击属性Hand Guidance Indicator右侧的○按钮,选择HeadsUpDirectionIndicatorPointer
- Hand Guidance Threshold取值:0.5
本节完成!
按下图发布到VS2015,并使用模拟器或者真机进行测试。
当拖拽的手势快超出检测范围时,会显示一个提醒箭头。
说明
在HandGuidance类中,主要用了InteractionManager这个交互管理器,来监听手势变化。
Chapter 4 - Manipulation
目标
拖拽移动Cube
实践
修改文件:”Assets/_Scenes/Holograms 211/Scripts/Cube211.cs”
using HoloToolkit.Unity.InputModule;
using UnityEngine;
public class Cube211 : MonoBehaviour, INavigationHandler, IManipulationHandler
[Tooltip("旋转速度")]
public float RotationSensitivity = 10.0f;
[Tooltip("移动速度")]
public float MoveSensitivity = 1.5f;
//Cube移动前的位置
private Vector3 origPosition;
public void OnManipulationCanceled(ManipulationEventData eventData)
//do nothing
public void OnManipulationCompleted(ManipulationEventData eventData)
//do nothing
public void OnManipulationStarted(ManipulationEventData eventData)
// 开始移动前,保存Cube原始位置
origPosition = transform.position;
public void OnManipulationUpdated(ManipulationEventData eventData)
// 获取拖拽的总偏移量
Vector3 newPos = new Vector3(eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z);
// 设置Cube新的位置
transform.position = origPosition + newPos * MoveSensitivity;
public void OnNavigationCanceled(NavigationEventData eventData)
//do nothing
public void OnNavigationCompleted(NavigationEventData eventData)
//do nothing
public void OnNavigationStarted(NavigationEventData eventData)
//do nothing
public void OnNavigationUpdated(NavigationEventData eventData)
// 计算旋转值,其中:eventData的CumulativeDelta返回导航差值,值域[-1, 1]
float rotationFactor = eventData.CumulativeDelta.x * RotationSensitivity;
transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
本节完成!
凝视Cube并拖拽,Cube将会发生移动。
如果上一节中的箭头会影响视线的话,可以去掉Controller的勾选框。
说明
- IManipulationHandler
手势移动事件处理接口,该事件会将返回自拖拽开始的总位移量。
小结
- Cursor及其子类:实现基础的光标
- INavigationHandler:手势导航事件的处理
- IManipulationHandler:手势移动事件的处理
- HandGuidance:手势超出检测区域的提醒
更多手势识别的处理,可以参考Unity SDK中提供的类:GestureRecognizer
参考文档
官方教程Holograms 211:https://developer.microsoft.com/en-us/windows/mixed-reality/holograms_211
VR/AR/MR技术交流QQ群:594299228
以上是关于Hololens官方教程精简版 - 04. Gesture(手势)的主要内容,如果未能解决你的问题,请参考以下文章
Hololens官方教程精简版 - 02. Introduction with Device
Hololens官方教程精简版 - 02. Introduction with Device
Hololens官方教程精简版 - 05. Voice(语音)
Hololens官方教程精简版 - 05. Voice(语音)