前期准备工作:
- 准备好一台满足Hololens开发环境的设备;(其中确认好Unity3D、Visual Studio的版本;)
- 从Github上获取微软提供的资源包(https://github.com/Microsoft/HolographicAcademy);
笔者此处使用的是Unity3D 2017.3.1f1,Visual Studio 2017。
(新版本的资源包支持在unity中调试)
本篇博文的内容在于介绍如何快速的使用资源包自带的场景(ModelExplorer.unity)来实现自定义手势输入功能。
笔者的操作方法是复制一个场景,然后删除一些不必要的游戏对象,只保留自己需要的。
- 手势输入;
导入资源包后,只需要为游戏对象写响应手势事件的脚本即可。
大概的工作流程是InputManager.cs等脚本构建了一个管理手势输入的对象,当对某个对象进行手势操作时,会调用相应的方法。它们有固定的名字,所以在写功能时需要注意方法名,此后手势对应什么功能则有写功能的同学来实现。
GestureAction.cs,对应AstroMan这一游戏对象。(此处截取部分代码)
void INavigationHandler.OnNavigationStarted(NavigationEventData eventData)
{
InputManager.Instance.PushModalInputHandler(gameObject);
}
void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
{
if (isNavigationEnabled)
{
/* TODO: DEVELOPER CODING EXERCISE 2.c */
// 2.c: Calculate a float rotationFactor based on eventData's NormalizedOffset.x multiplied by RotationSensitivity.
// This will help control the amount of rotation.
float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;
// 2.c: transform.Rotate around the Y axis using rotationFactor.
transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
}
}
void INavigationHandler.OnNavigationCompleted(NavigationEventData eventData)
{
InputManager.Instance.PopModalInputHandler();
}
void INavigationHandler.OnNavigationCanceled(NavigationEventData eventData)
{
InputManager.Instance.PopModalInputHandler();
}
使用时需要留意Navigation和Manipulation,过后会补充这方面的内容。
- 手势功能切换
完成手势功能后,因为Hololens支持的手势有限,那么只能够通过切换手势代表的功能这一方法来补充这个短板。
那么手势功能的切换方式有很多,官方给出了支持语音切换的解决方案,此处不细谈。
void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
{
//如果isNavigationEnabled为真则执行如下功能
if (isNavigationEnabled)
{
float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;
transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
}
}
void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
{
//如果isNavigationEnabled为假则执行如下功能
if (!isNavigationEnabled)
{
transform.position = manipulationOriginalPosition + eventData.CumulativeDelta;
}
}
void ISpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
{
if (eventData.RecognizedText.ToLower().Equals("move astronaut"))
{
//通过官方的支持识别到"move astronaut"的语音时修改isNavigationEnabled的值
isNavigationEnabled = false;
}
else if (eventData.RecognizedText.ToLower().Equals("rotate astronaut"))
{
isNavigationEnabled = true;
}
else
{
return;
}
eventData.Use();
}
具体用哪种方式由自己去决定,具体的实现并不复杂,此处的方法是比较快捷的,但是如果项目足够大时肯定要另寻出路。