HoloLens开发3:手势控制物体旋转
1.导入HoloToolKit插件删除场景初始MainCamera,并将插件中MainCamera预制件拖入Hierarchy面板中。或者将场景初始主相机的Camera做如下设置:2.添加功能脚本在Project面板中查找CursorWithFeedBack预制件,拖入Hierarchy面板。并在其组件中添加GazeManager.cs、GestureManager.cs、Ha
1.导入HoloToolKit插件
删除场景初始MainCamera,并将插件中MainCamera预制件拖入Hierarchy面板中。
或者将场景初始主相机的Camera做如下设置:
2.添加功能脚本
在Project面板中查找CursorWithFeedBack预制件,拖入Hierarchy面板。并在其组件中添加GazeManager.cs、GestureManager.cs、HandsManager.cs、KeyWordManager.cs、InteractibleManager.cs。插件中没有存在的脚本为:Interactible.cs、InteractibleManager.cs
新建两个脚本,分别命名为Interactible.cs、InteractibleManager.cs。内容如下:
using HoloToolkit;
using UnityEngine;
///<summary>
/// InteractibleManager keeps tracks ofwhich GameObject
/// is currently in focus.
///</summary>
namespace HoloToolkit.Unity
{
publicclassInteractibleManager :Singleton<InteractibleManager>
{
publicGameObject FocusedGameObject {get; privateset; }
privateGameObject oldFocusedGameObject =null;
void Start()
{
FocusedGameObject = null;
}
void Update()
{
/* TODO: DEVELOPER CODING EXERCISE 2.c */
oldFocusedGameObject =FocusedGameObject;
if (GazeManager.Instance.Hit)
{
RaycastHit hitInfo =GazeManager.Instance.HitInfo;
if (hitInfo.collider !=null)
{
// 2.c: Assign the hitInfo's collidergameObject to the FocusedGameObject.
FocusedGameObject =hitInfo.collider.gameObject;
}
else
{
FocusedGameObject =null;
}
}
else
{
FocusedGameObject =null;
}
if (FocusedGameObject != oldFocusedGameObject)
{
ResetFocusedInteractible();
if (FocusedGameObject !=null)
{
if (FocusedGameObject.GetComponent<Interactible>() !=null)
{
// 2.c: Send a GazeEntered messageto the FocusedGameObject.
FocusedGameObject.SendMessage("GazeEntered");
}
}
}
}
privatevoidResetFocusedInteractible()
{
if (oldFocusedGameObject !=null)
{
if (oldFocusedGameObject.GetComponent<Interactible>() !=null)
{
// 2.c: Send a GazeExited message to theoldFocusedGameObject.
oldFocusedGameObject.SendMessage("GazeExited");
}
}
}
}
}
using UnityEngine;
///<summary>
/// The Interactible class flags a GameObject as being "Interactible".
/// Determines what happens when anInteractible is being gazed at.
///</summary>
publicclassInteractible :MonoBehaviour
{
[Tooltip("Audioclip to play when interacting with this hologram.")]
publicAudioClip TargetFeedbackSound;
privateAudioSource audioSource;
privateMaterial[] defaultMaterials;
void Start()
{
defaultMaterials = GetComponent<Renderer>().materials;
// Add a BoxCollider if the interactible doesnot contain one.
Collider collider = GetComponentInChildren<Collider>();
if (collider ==null)
{
gameObject.AddComponent<BoxCollider>();
}
EnableAudioHapticFeedback();
}
privatevoid EnableAudioHapticFeedback()
{
// If this hologram has an audio clip, add anAudioSource with this clip.
if (TargetFeedbackSound !=null)
{
audioSource = GetComponent<AudioSource>();
if (audioSource ==null)
{
audioSource =gameObject.AddComponent<AudioSource>();
}
audioSource.clip =TargetFeedbackSound;
audioSource.playOnAwake =false;
audioSource.spatialBlend = 1;
audioSource.dopplerLevel = 0;
}
}
/* TODO: DEVELOPER CODING EXERCISE 2.d */
void GazeEntered()
{
for (int i = 0; i <defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to highlightthe material when gaze enters.
defaultMaterials[i].SetFloat("_Highlight", .25f);
}
}
void GazeExited()
{
for (int i = 0; i <defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to remove highlighton material when gaze exits.
defaultMaterials[i].SetFloat("_Highlight", 0f);
}
}
void OnSelect()
{
for (int i = 0; i <defaultMaterials.Length; i++)
{
defaultMaterials[i].SetFloat("_Highlight", .5f);
}
// Play the audioSource feedback when we gazeand select a hologram.
if (audioSource !=null && !audioSource.isPlaying)
{
audioSource.Play();
}
/* TODO: DEVELOPER CODING EXERCISE 6.a */
// 6.a: Handle the OnSelect by sending aPerformTagAlong message.
}
}
3.修改原插件代码
修改GestureManager.cs脚本
using UnityEngine;
using UnityEngine.VR.WSA.Input;
using System;
namespace HoloToolkit.Unity
{
///<summary>
/// GestureManagercreates a gesture recognizer and signs up for a tap gesture.
/// When a tapgesture is detected, GestureManager uses GazeManager to find the game object.
/// GestureManagerthen sends a message to that game object.
///</summary>
[RequireComponent(typeof(GazeManager))]
publicpartialclassGestureManager :Singleton<GestureManager>
{
///<summary>
/// Key to press in the editor to select the currently gazedhologram
///</summary>
publicKeyCode EditorSelectKey =KeyCode.Space;
///<summary>
/// To select even when a hologram is not being gazed at,
/// set the override focused object.
/// If its null, then the gazed at object will be selected.
///</summary>
publicGameObject OverrideFocusedObject
{
get;set;
}
///<summary>
/// Gets the currently focused object, or null if none.
///</summary>
//public GameObject FocusedObject
//{
// get { return focusedObject; }
//}
//private GameObject focusedObject;
// Tap and Navigation gesture recognizer.
publicGestureRecognizer NavigationRecognizer {get; privateset; }
// Manipulation gesture recognizer.
publicGestureRecognizer ManipulationRecognizer {get; privateset; }
// Currently active gesture recognizer.
publicGestureRecognizer ActiveRecognizer {get; privateset; }
publicbool IsManipulating{get; privateset; }
publicVector3 ManipulationPosition {get; privateset; }
//导航手势
publicbool IsNavigating {get;privateset; }
//导航位置
publicVector3 NavigationPosition {get; privateset; }
void Start()
{
/* TODO: DEVELOPER CODING EXERCISE 2.b */
// 2.b:实例化NavigationRecognizer.
NavigationRecognizer = newGestureRecognizer();
// 2.b:将导航手势设置添加到导航识别器的可识别手势.
NavigationRecognizer.SetRecognizableGestures(
GestureSettings.Tap |
GestureSettings.NavigationX);
// 2.b: 注册按下手势事件
NavigationRecognizer.TappedEvent +=NavigationRecognizer_TappedEvent;
// 2.b: 注册开始事件
NavigationRecognizer.NavigationStartedEvent +=NavigationRecognizer_NavigationStartedEvent;
// 2.b:注册手势更新事件.
NavigationRecognizer.NavigationUpdatedEvent +=NavigationRecognizer_NavigationUpdatedEvent;
// 2.b: 注册手势完成事件
NavigationRecognizer.NavigationCompletedEvent +=NavigationRecognizer_NavigationCompletedEvent;
// 2.b: 注册手势取消事件
NavigationRecognizer.NavigationCanceledEvent +=NavigationRecognizer_NavigationCanceledEvent;
// Instantiate the ManipulationRecognizer.
ManipulationRecognizer =newGestureRecognizer();
// Add the ManipulationTranslateGestureSetting to the ManipulationRecognizer's RecognizableGestures.
ManipulationRecognizer.SetRecognizableGestures(
GestureSettings.ManipulationTranslate);
// Register for the Manipulation events onthe ManipulationRecognizer.
ManipulationRecognizer.ManipulationStartedEvent += ManipulationRecognizer_ManipulationStartedEvent;
ManipulationRecognizer.ManipulationUpdatedEvent +=ManipulationRecognizer_ManipulationUpdatedEvent;
ManipulationRecognizer.ManipulationCompletedEvent +=ManipulationRecognizer_ManipulationCompletedEvent;
ManipulationRecognizer.ManipulationCanceledEvent +=ManipulationRecognizer_ManipulationCanceledEvent;
ResetGestureRecognizers();
}
///<summary>
/// Revert back to the default GestureRecognizer.
///</summary>
publicvoidResetGestureRecognizers()
{
// Default to the navigation gestures.
Transition(NavigationRecognizer);
}
///<summary>
/// Transition to a new GestureRecognizer.
///</summary>
///<param name="newRecognizer">The GestureRecognizer to transitionto.</param>
publicvoid Transition(GestureRecognizer newRecognizer)
{
if (newRecognizer ==null)
{
return;
}
if (ActiveRecognizer !=null)
{
if (ActiveRecognizer == newRecognizer)
{
return;
}
ActiveRecognizer.CancelGestures();
ActiveRecognizer.StopCapturingGestures();
}
newRecognizer.StartCapturingGestures();
ActiveRecognizer = newRecognizer;
}
privatevoidNavigationRecognizer_NavigationStartedEvent(InteractionSourceKind source, Vector3 relativePosition,Ray ray)
{
// 2.b: Set IsNavigating to be true.
IsNavigating = true;
// 2.b: Set NavigationPosition to berelativePosition.
NavigationPosition =relativePosition;
}
privatevoidNavigationRecognizer_NavigationCompletedEvent(InteractionSourceKind source, Vector3 relativePosition,Ray ray)
{
// 2.b: Set IsNavigating to be false.
IsNavigating = false;
}
privatevoidNavigationRecognizer_NavigationUpdatedEvent(InteractionSourceKind source, Vector3 relativePosition,Ray ray)
{
// 2.b: Set IsNavigating to be true.
IsNavigating = true;
// 2.b: SetNavigationPosition to be relativePosition.
NavigationPosition =relativePosition;
}
privatevoidNavigationRecognizer_NavigationCanceledEvent(InteractionSourceKind source, Vector3 relativePosition,Ray ray)
{
// 2.b: Set IsNavigating to be false.
IsNavigating = false;
}
privatevoidManipulationRecognizer_ManipulationStartedEvent(InteractionSourceKind source, Vector3 position,Ray ray)
{
if (HandsManager.Instance.FocusedGameObject!=null)
{
IsManipulating =true;
ManipulationPosition =position;
HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationStart", position);
}
}
privatevoidManipulationRecognizer_ManipulationUpdatedEvent(InteractionSourceKind source, Vector3 position,Ray ray)
{
if (HandsManager.Instance.FocusedGameObject!=null)
{
IsManipulating =true;
ManipulationPosition =position;
HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationUpdate", position);
}
}
privatevoidManipulationRecognizer_ManipulationCompletedEvent(InteractionSourceKind source, Vector3 position,Ray ray)
{
IsManipulating = false;
}
privatevoidManipulationRecognizer_ManipulationCanceledEvent(InteractionSourceKind source, Vector3 position,Ray ray)
{
IsManipulating = false;
}
privatevoidNavigationRecognizer_TappedEvent(InteractionSourceKind source, int tapCount,Ray ray)
{
GameObject focusedObject =InteractibleManager.Instance.FocusedGameObject;
if (focusedObject !=null)
{
focusedObject.SendMessageUpwards("OnSelect");
}
}
void OnDestroy()
{
// 2.b: Unregister the Tapped and Navigationevents on the NavigationRecognizer.
NavigationRecognizer.TappedEvent -=NavigationRecognizer_TappedEvent;
NavigationRecognizer.NavigationStartedEvent -=NavigationRecognizer_NavigationStartedEvent;
NavigationRecognizer.NavigationUpdatedEvent -=NavigationRecognizer_NavigationUpdatedEvent;
NavigationRecognizer.NavigationCompletedEvent -=NavigationRecognizer_NavigationCompletedEvent;
NavigationRecognizer.NavigationCanceledEvent-= NavigationRecognizer_NavigationCanceledEvent;
// Unregister the Manipulation events on theManipulationRecognizer.
ManipulationRecognizer.ManipulationStartedEvent -=ManipulationRecognizer_ManipulationStartedEvent;
ManipulationRecognizer.ManipulationUpdatedEvent -=ManipulationRecognizer_ManipulationUpdatedEvent;
ManipulationRecognizer.ManipulationCompletedEvent -=ManipulationRecognizer_ManipulationCompletedEvent;
ManipulationRecognizer.ManipulationCanceledEvent-= ManipulationRecognizer_ManipulationCanceledEvent;
}
}
}
4.控制旋转
将需要旋转的物体添加控制旋转脚本GestureAction.cs
using UnityEngine;
using System.Collections;
///<summary>
///手势动作根据正在执行的手势执行自定义操作。
///</summary>
namespace HoloToolkit.Unity //可用using HoloToolkit.Unity;替代
{
publicclassGestureAction :MonoBehaviour
{
[Tooltip("Rotation max speed controls amount ofrotation.")]
publicfloatRotationSensitivity = 10.0f;
privateVector3 _manipulationPreviousPosition;
privatefloat_rotationFactor;
void Update()
{
PerformRotation();
}
privatevoidPerformRotation()
{
if (GestureManager.Instance.IsNavigating&&HandsManager.Instance.FocusedGameObject ==gameObject)
{
// 2.c: 基于手势管理器的NavigationPosition.x轴乘以旋转灵敏度计算旋转量,有助于控制旋转量。
_rotationFactor = GestureManager.Instance.NavigationPosition.x * RotationSensitivity;
// 2.c: 绕Z轴旋转 根据实际需要选择需要沿轴旋转的轴
transform.Rotate(newVector3(0,0, -1f * _rotationFactor));
}
}
void PerformManipulationStart(Vector3 position)
{
_manipulationPreviousPosition =position;
}
void PerformManipulationUpdate(Vector3 position)
{
if (GestureManager.Instance.IsManipulating)
{
Vector3 moveVector =Vector3.zero;
}
}
}
}
5.运行测试
使用“空气点”和“保持”手势控制物体旋转,取消手势后取消旋转。
更多推荐
所有评论(0)