Hololens开发笔记之Gesture手势识别(手势检测反馈)
本文实现当使用者手出现在Hololens视野范围内时,跟踪手并给出反馈的效果。
1、在Manager上添加HandsManager脚本组件,用于追踪识别手

HandsManager.cs如下(直接使用HoloTooKit中脚本)
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information. using System.Collections.Generic;
using UnityEngine.VR.WSA.Input; namespace HoloToolkit.Unity
{
/// <summary>
/// HandsManager determines if the hand is currently detected or not.
/// </summary>
public partial class HandsManager : Singleton<HandsManager>
{
/// <summary>
/// HandDetected tracks the hand detected state.
/// Returns true if the list of tracked hands is not empty.
/// </summary>
public bool HandDetected
{
get { return trackedHands.Count > ; }
} private HashSet<uint> trackedHands = new HashSet<uint>(); void Awake()
{
//识别到来源
InteractionManager.SourceDetected += InteractionManager_SourceDetected;
//来源丢失
InteractionManager.SourceLost += InteractionManager_SourceLost;
} private void InteractionManager_SourceDetected(InteractionSourceState state)
{
// 检测来源是否为手,如果是手则加入跟踪集合
if (state.source.kind != InteractionSourceKind.Hand)
{
return;
} trackedHands.Add(state.source.id);
} private void InteractionManager_SourceLost(InteractionSourceState state)
{
// 检测丢失的来源是否为手,如果是手则从跟踪集合中去除
if (state.source.kind != InteractionSourceKind.Hand)
{
return;
} if (trackedHands.Contains(state.source.id))
{
trackedHands.Remove(state.source.id);
}
} void OnDestroy()
{
InteractionManager.SourceDetected -= InteractionManager_SourceDetected;
InteractionManager.SourceLost -= InteractionManager_SourceLost;
}
}
}
该脚本中使用到了底层API Interaction Input
底层API运行获得输入来源的更多详细信息,例如它在世界中的位置和速度。
如何处理底层交互事件
使用底层交互是很容易的:
1) 注册InteractionManager事件
2) 处理事件
停止它也很容易:
1) 取消注册事件
处理底层交互事件
一旦注册了底层交互事件,在事件发生时你就可以得到回调。你可以使用获取到的时间信息来处理应用行为。
void InteractionManager_SourcePressed(InteractionSourceState state)
{
// state变量里包含以下信息:
// 当前凝视射线信息
// 来源是否被点击
// 位置、速度之类的属性
// 来源id和来源类型 ( hand, voice, controller或其他)
}
如何停止交互事件
当你不再想要关注一些事件后,只需要取消时间注册即可。
InteractionManager.SourcePressed -= InteractionManager_SourcePressed;
输入源变化事件
这些事件描述了输入源的当前状态:
1) detected( 即将激活)
2) lost( 即将取消激活)
3) updates( 移动或者一些状态在变化)
4) is pressed( 点击、按钮按下或者语音选中)
5) is released( 点击结束,按钮松开,语音选中结束)
输入源状态
每个事件都会有一个InteractionSourceState参数,这个参数代表了实时输入源状态:
1) 是否是点击状态
2) InteractionSourceProperties包含了输入源位置信息 InteractionSourceLocation,能够获得当前输入源位置和速度信息
3) 凝视射线信息,用于判断事件发生时用户是否在注视目标
4) 来源类型信息,包括hand、voice、controller或者其他类型
2、在Cursor下新建Empty对象,并重命名为CursorBillboard,并添加Billboard脚本组件

Billboard脚本如下(可以直接在HoloToolKit中找到)
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information. using UnityEngine; namespace HoloToolkit.Unity
{
public enum PivotAxis
{
// Rotate about all axes.
Free,
// Rotate about an individual axis.
X,
Y
} /// <summary>
/// The Billboard class implements the behaviors needed to keep a GameObject
/// oriented towards the user.
/// </summary>
public class Billboard : MonoBehaviour
{
/// <summary>
/// The axis about which the object will rotate.
/// </summary>
[Tooltip("Specifies the axis about which the object will rotate (Free rotates about both X and Y).")]
public PivotAxis PivotAxis = PivotAxis.Free; /// <summary>
/// Overrides the cached value of the GameObject's default rotation.
/// </summary>
public Quaternion DefaultRotation { get; private set; } private void Awake()
{
// Cache the GameObject's default rotation.
DefaultRotation = gameObject.transform.rotation;
} /// <summary>
/// Keeps the object facing the camera.
/// </summary>
private void Update()
{
// Get a Vector that points from the Camera to the target.
Vector3 forward;
Vector3 up; // Adjust for the pivot axis. We need a forward and an up for use with Quaternion.LookRotation
switch (PivotAxis)
{
// If we're fixing one axis, then we're projecting the camera's forward vector onto
// the plane defined by the fixed axis and using that as the new forward.
case PivotAxis.X:
Vector3 right = transform.right; // Fixed right
forward = Vector3.ProjectOnPlane(Camera.main.transform.forward, right).normalized;
up = Vector3.Cross(forward, right); // Compute the up vector
break; case PivotAxis.Y:
up = transform.up; // Fixed up
forward = Vector3.ProjectOnPlane(Camera.main.transform.forward, up).normalized;
break; // If the axes are free then we're simply aligning the forward and up vectors
// of the object with those of the camera.
case PivotAxis.Free:
default:
forward = Camera.main.transform.forward;
up = Camera.main.transform.up;
break;
} // Calculate and apply the rotation required to reorient the object
transform.rotation = Quaternion.LookRotation(forward, up);
}
}
}
3、在Cursor上添加CursorFeedback脚本组件

1) 在HoloToolkit -> Input -> Prefabs中找到HandDetectedFeedback Prefab 并拖到CursorFeedback的hand detected asset上
2) 将刚才创建的CursorBillboard拖到CursorFeedback的Feedback Parent上
CursorFeedback脚本如下((可以直接在HoloToolKit中找到))
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information. using UnityEngine; namespace HoloToolkit.Unity
{
/// <summary>
/// CursorFeedback class takes GameObjects to give cursor feedback
/// to users based on different states.
/// </summary>
public class CursorFeedback : MonoBehaviour
{
[Tooltip("Drag a prefab object to display when a hand is detected.")]
public GameObject HandDetectedAsset;
private GameObject handDetectedGameObject; [Tooltip("Drag a prefab object to parent the feedback assets.")]
public GameObject FeedbackParent; void Awake()
{
if (HandDetectedAsset != null)
{
handDetectedGameObject = InstantiatePrefab(HandDetectedAsset);
}
else
{
Debug.LogError("Missing a required game object asset. Check HandDetectedAsset is not null in editor.");
}
} private GameObject InstantiatePrefab(GameObject inputPrefab)
{
GameObject instantiatedPrefab = null; if (inputPrefab != null && FeedbackParent != null)
{
instantiatedPrefab = GameObject.Instantiate(inputPrefab);
// Assign parent to be the FeedbackParent
// so that feedback assets move and rotate with this parent.
instantiatedPrefab.transform.parent = FeedbackParent.transform; // Set starting state of the prefab's GameObject to be inactive.
instantiatedPrefab.gameObject.SetActive(false);
}
else
{
Debug.LogError("Missing a required game object asset. Check FeedbackParent is not null in editor.");
} return instantiatedPrefab;
} void Update()
{
UpdateHandDetectedState();
} private void UpdateHandDetectedState()
{
if (handDetectedGameObject == null)
{
return;
} handDetectedGameObject.SetActive(HandsManager.Instance.HandDetected);
}
}
}
4、运行测试
当手出现在Hololens视野中时,手被检测到,在凝视射线处出现一个蓝色的小手(Hololens模拟器中需要处于hold状态才会出现蓝色小手,真机上只要手举起就可以)

Hololens开发笔记之Gesture手势识别(手势检测反馈)的更多相关文章
- Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体旋转)
Manipulation gesture:保持点击手势,在3D世界中绝对运动 当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动.缩放或旋转全息图像.如此的一个用处是使得用户可以在世界中绘 ...
- Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体平移)
Manipulation gesture:保持点击手势,在3D世界中绝对运动 当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动.缩放或旋转全息图像.如此的一个用处是使得用户可以在世界中绘 ...
- HoloLens开发笔记之Gesture input手势输入
手势是HoloLens三个首要输入形式之一.一旦你使用凝视定位了一个全息图像,手势允许你与它交互.手势输入允许你使用手或者点击器原生地与全息图像交互. 手势之外,你也可以在应用中使用语音输入来交互. ...
- Hololens开发笔记之Gesture手势识别(单击,双击)
本文使用手势识别实现识别单击及双击手势的功能,当单击Cube时改变颜色为蓝色,当双击Cube时改变颜色为绿色. 手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层 ...
- Hololens开发笔记之Gesture手势识别(基本介绍)
手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层API,可以满足不同的手势定制需求.底层API能够获取手的位置和速度信息,高层API则借助手势识别器来识别预设的 ...
- Hololens开发笔记之使用Unity开发一个简单的应用
一.Hololens概述 Hololens有以下特性 1.空间映射借助微软特殊定制的全息处理单元(HPU),HoloLens 实现了对周边环境的快速扫描和空间匹配.这保证了 HoloLens能够准确地 ...
- Android开发笔记——图片缓存、手势及OOM分析
把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...
- Hololens开发笔记之连接PC实现资源共享
官网原文介绍:https://developer.microsoft.com/en-us/windows/holographic/using_the_windows_device_portal Hol ...
- Hololens开发笔记:UDP接收数据
Hololens的应用需要与其他设备通信的时候,UDP是比较方便的一种方式,Unity3d 2017.3 C#开发的时候可以用Windows.Networking.Sockets.DatagramSo ...
随机推荐
- iOS开发Swift篇—(四)运算符
iOS开发Swift篇—(四)运算符 一.运算符 1.Swift所支持的部分运算符有以下一些 赋值运算符:= 复合赋值运算符:+=.-= 算术运算符:+.-.*./ 求余运算符:% 自增.自减运算符: ...
- qsort函数
qsort函数用法举例 #include <stdio.h> #include <stdlib.h> #include <string.h> //数字比较函数 in ...
- 计算机网络(7)-----TCP协议概述
传输控制协议(Transmission Control Protocol) 概念 一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中,它 ...
- windows server域的概念以及wmic(centos上命令)
wmic访问在域中的计算机.其中ops\administrator为域用户名,也可以写作ops.com\administrator.ops是域名ops.com的简写,是MS的NetBIOS一套吗? . ...
- Android Framework层Power键关机流程(二,关机流程)
二,关机流程 从前一篇博文我们知道,当用户长按Power键时会弹出(关机.重启,飞行模式等选项)对话框,我们点击关机,则会弹出关机确认对话框.那么从选项对话框到关机确认对话框又是一个什么流程呢.下面我 ...
- Spring框架学习(一)
一.概述 spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器.为软件开发提供全方位支持的应用程序框架. 二.控制反转(In ...
- Myeclipse+Axis2+Tomcat开发webService
1. 下载文件: 需要在axis2官网下载两种类型的axis2文件,bin版和war版(下载地址:http://axis.apache.org/axis2/java/core/download.cg ...
- Day17_集合第三天
1.HashSet类(掌握) 1.哈希值概念 哈希值:哈希值就是调用对象的hashCode()方法后返回的一个int型数字 哈希桶:简单点理解就是存储相同哈希值对象的一个容器 1. ...
- 在maven项目中解决第三方jar包依赖的问题
在maven项目中,对于那些在maven仓库中不存在的第三方jar,依赖解决通常有如下解决方法: 方法1:直接将jar包拷贝到项目指定目录下,然后在pom文件中指定依赖类型为system,如: < ...
- 20160621-BAPI 更改外向DN&更改拣配
参考代码转自:http://blog.sina.com.cn/s/blog_4c66402b01012lgr.html 感谢. 测试一把,再做总结. 1.更改外向交货单: 2.更改内向交货单. htt ...