当前位置:   article > 正文

Hololens入门之手势识别(手检测反馈)_honolens获得手势射线代码

honolens获得手势射线代码

Hololens入门之手势识别(手检测反馈)

本文实现当使用者手出现在Hololens视野范围内时,跟踪手并给出反馈的效果。

1、在Manager上添加HandsManager脚本组件,用于追踪识别手


HandsManager.cs如下(直接使用HoloTooKit中脚本)

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. using System.Collections.Generic;
  4. using UnityEngine.VR.WSA.Input;
  5. namespace HoloToolkit.Unity
  6. {
  7. /// <summary>
  8. /// HandsManager determines if the hand is currently detected or not.
  9. /// </summary>
  10. public partial class HandsManager : Singleton<HandsManager>
  11. {
  12. /// <summary>
  13. /// HandDetected tracks the hand detected state.
  14. /// Returns true if the list of tracked hands is not empty.
  15. /// </summary>
  16. public bool HandDetected
  17. {
  18. get { return trackedHands.Count > 0; }
  19. }
  20. private HashSet<uint> trackedHands = new HashSet<uint>();
  21. void Awake()
  22. {
  23. //识别到来源
  24. InteractionManager.SourceDetected += InteractionManager_SourceDetected;
  25. //来源丢失
  26. InteractionManager.SourceLost += InteractionManager_SourceLost;
  27. }
  28. private void InteractionManager_SourceDetected(InteractionSourceState state)
  29. {
  30. // 检测来源是否为手,如果是手则加入跟踪集合
  31. if (state.source.kind != InteractionSourceKind.Hand)
  32. {
  33. return;
  34. }
  35. trackedHands.Add(state.source.id);
  36. }
  37. private void InteractionManager_SourceLost(InteractionSourceState state)
  38. {
  39. // 检测丢失的来源是否为手,如果是手则从跟踪集合中去除
  40. if (state.source.kind != InteractionSourceKind.Hand)
  41. {
  42. return;
  43. }
  44. if (trackedHands.Contains(state.source.id))
  45. {
  46. trackedHands.Remove(state.source.id);
  47. }
  48. }
  49. void OnDestroy()
  50. {
  51. InteractionManager.SourceDetected -= InteractionManager_SourceDetected;
  52. InteractionManager.SourceLost -= InteractionManager_SourceLost;
  53. }
  54. }
  55. }


该脚本中使用到了底层API   Interaction Input

底层API运行获得输入来源的更多详细信息,例如它在世界中的位置和速度。

如何处理底层交互事件
使用底层交互是很容易的:
1) 注册InteractionManager事件
2) 处理事件
停止它也很容易:
1) 取消注册事件

处理底层交互事件
一旦注册了底层交互事件,在事件发生时你就可以得到回调。你可以使用获取到的时间信息来处理应用行为。

  1. void InteractionManager_SourcePressed(InteractionSourceState state)
  2. {
  3. // state变量里包含以下信息:
  4. // 当前凝视射线信息
  5. // 来源是否被点击
  6. // 位置、速度之类的属性
  7. // 来源id和来源类型 ( hand, voice, controller或其他)
  8. }

如何停止交互事件
当你不再想要关注一些事件后,只需要取消时间注册即可。

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中找到)

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. using UnityEngine;
  4. namespace HoloToolkit.Unity
  5. {
  6. public enum PivotAxis
  7. {
  8. // Rotate about all axes.
  9. Free,
  10. // Rotate about an individual axis.
  11. X,
  12. Y
  13. }
  14. /// <summary>
  15. /// The Billboard class implements the behaviors needed to keep a GameObject
  16. /// oriented towards the user.
  17. /// </summary>
  18. public class Billboard : MonoBehaviour
  19. {
  20. /// <summary>
  21. /// The axis about which the object will rotate.
  22. /// </summary>
  23. [Tooltip("Specifies the axis about which the object will rotate (Free rotates about both X and Y).")]
  24. public PivotAxis PivotAxis = PivotAxis.Free;
  25. /// <summary>
  26. /// Overrides the cached value of the GameObject's default rotation.
  27. /// </summary>
  28. public Quaternion DefaultRotation { get; private set; }
  29. private void Awake()
  30. {
  31. // Cache the GameObject's default rotation.
  32. DefaultRotation = gameObject.transform.rotation;
  33. }
  34. /// <summary>
  35. /// Keeps the object facing the camera.
  36. /// </summary>
  37. private void Update()
  38. {
  39. // Get a Vector that points from the Camera to the target.
  40. Vector3 forward;
  41. Vector3 up;
  42. // Adjust for the pivot axis. We need a forward and an up for use with Quaternion.LookRotation
  43. switch (PivotAxis)
  44. {
  45. // If we're fixing one axis, then we're projecting the camera's forward vector onto
  46. // the plane defined by the fixed axis and using that as the new forward.
  47. case PivotAxis.X:
  48. Vector3 right = transform.right; // Fixed right
  49. forward = Vector3.ProjectOnPlane(Camera.main.transform.forward, right).normalized;
  50. up = Vector3.Cross(forward, right); // Compute the up vector
  51. break;
  52. case PivotAxis.Y:
  53. up = transform.up; // Fixed up
  54. forward = Vector3.ProjectOnPlane(Camera.main.transform.forward, up).normalized;
  55. break;
  56. // If the axes are free then we're simply aligning the forward and up vectors
  57. // of the object with those of the camera.
  58. case PivotAxis.Free:
  59. default:
  60. forward = Camera.main.transform.forward;
  61. up = Camera.main.transform.up;
  62. break;
  63. }
  64. // Calculate and apply the rotation required to reorient the object
  65. transform.rotation = Quaternion.LookRotation(forward, up);
  66. }
  67. }
  68. }

3、在Cursor上添加CursorFeedback脚本组件


1) 在HoloToolkit -> Input -> Prefabs中找到HandDetectedFeedback Prefab 并拖到CursorFeedback的hand detected asset上

2) 将刚才创建的CursorBillboard拖到CursorFeedback的Feedback Parent上

CursorFeedback脚本如下((可以直接在HoloToolKit中找到))

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. using UnityEngine;
  4. namespace HoloToolkit.Unity
  5. {
  6. /// <summary>
  7. /// CursorFeedback class takes GameObjects to give cursor feedback
  8. /// to users based on different states.
  9. /// </summary>
  10. public class CursorFeedback : MonoBehaviour
  11. {
  12. [Tooltip("Drag a prefab object to display when a hand is detected.")]
  13. public GameObject HandDetectedAsset;
  14. private GameObject handDetectedGameObject;
  15. [Tooltip("Drag a prefab object to parent the feedback assets.")]
  16. public GameObject FeedbackParent;
  17. void Awake()
  18. {
  19. if (HandDetectedAsset != null)
  20. {
  21. handDetectedGameObject = InstantiatePrefab(HandDetectedAsset);
  22. }
  23. else
  24. {
  25. Debug.LogError("Missing a required game object asset. Check HandDetectedAsset is not null in editor.");
  26. }
  27. }
  28. private GameObject InstantiatePrefab(GameObject inputPrefab)
  29. {
  30. GameObject instantiatedPrefab = null;
  31. if (inputPrefab != null && FeedbackParent != null)
  32. {
  33. instantiatedPrefab = GameObject.Instantiate(inputPrefab);
  34. // Assign parent to be the FeedbackParent
  35. // so that feedback assets move and rotate with this parent.
  36. instantiatedPrefab.transform.parent = FeedbackParent.transform;
  37. // Set starting state of the prefab's GameObject to be inactive.
  38. instantiatedPrefab.gameObject.SetActive(false);
  39. }
  40. else
  41. {
  42. Debug.LogError("Missing a required game object asset. Check FeedbackParent is not null in editor.");
  43. }
  44. return instantiatedPrefab;
  45. }
  46. void Update()
  47. {
  48. UpdateHandDetectedState();
  49. }
  50. private void UpdateHandDetectedState()
  51. {
  52. if (handDetectedGameObject == null)
  53. {
  54. return;
  55. }
  56. handDetectedGameObject.SetActive(HandsManager.Instance.HandDetected);
  57. }
  58. }
  59. }

4、运行测试

当手出现在Hololens视野中时,手被检测到,在凝视射线处出现一个蓝色的小手(Hololens模拟器中需要处于hold状态才会出现蓝色小手,真机上只要手举起就可以)


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/89371
推荐阅读
相关标签
  

闽ICP备14008679号