FingerDirectionDetector.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using System;
  2. using System.Collections;
  3. using Leap.Unity.Attributes;
  4. using UnityEngine;
  5. namespace Leap.Unity
  6. {
  7. public class FingerDirectionDetector : Detector
  8. {
  9. private void OnValidate()
  10. {
  11. if (this.OffAngle < this.OnAngle)
  12. {
  13. this.OffAngle = this.OnAngle;
  14. }
  15. }
  16. private void Awake()
  17. {
  18. this.watcherCoroutine = this.fingerPointingWatcher();
  19. }
  20. private void OnEnable()
  21. {
  22. base.StartCoroutine(this.watcherCoroutine);
  23. }
  24. private void OnDisable()
  25. {
  26. base.StopCoroutine(this.watcherCoroutine);
  27. this.Deactivate();
  28. }
  29. private IEnumerator fingerPointingWatcher()
  30. {
  31. int selectedFinger = this.selectedFingerOrdinal();
  32. for (;;)
  33. {
  34. if (this.HandModel != null)
  35. {
  36. Hand hand = this.HandModel.GetLeapHand();
  37. if (hand != null)
  38. {
  39. Vector3 targetDirection = this.selectedDirection(hand.Fingers[selectedFinger].TipPosition.ToVector3());
  40. Vector3 fingerDirection = hand.Fingers[selectedFinger].Bone(Bone.BoneType.TYPE_DISTAL).Direction.ToVector3();
  41. float num = Vector3.Angle(fingerDirection, targetDirection);
  42. if (this.HandModel.IsTracked && num <= this.OnAngle)
  43. {
  44. this.Activate();
  45. }
  46. else if (!this.HandModel.IsTracked || num >= this.OffAngle)
  47. {
  48. this.Deactivate();
  49. }
  50. }
  51. }
  52. yield return new WaitForSeconds(this.Period);
  53. }
  54. yield break;
  55. }
  56. private Vector3 selectedDirection(Vector3 tipPosition)
  57. {
  58. switch (this.PointingType)
  59. {
  60. case PointingType.RelativeToCamera:
  61. return Camera.main.transform.TransformDirection(this.PointingDirection);
  62. case PointingType.RelativeToHorizon:
  63. {
  64. float y = Camera.main.transform.rotation.eulerAngles.y;
  65. Quaternion rotation = Quaternion.AngleAxis(y, Vector3.up);
  66. return rotation * this.PointingDirection;
  67. }
  68. case PointingType.RelativeToWorld:
  69. return this.PointingDirection;
  70. case PointingType.AtTarget:
  71. return this.TargetObject.position - tipPosition;
  72. default:
  73. return this.PointingDirection;
  74. }
  75. }
  76. private int selectedFingerOrdinal()
  77. {
  78. switch (this.FingerName)
  79. {
  80. case Finger.FingerType.TYPE_THUMB:
  81. return 0;
  82. case Finger.FingerType.TYPE_INDEX:
  83. return 1;
  84. case Finger.FingerType.TYPE_MIDDLE:
  85. return 2;
  86. case Finger.FingerType.TYPE_RING:
  87. return 3;
  88. case Finger.FingerType.TYPE_PINKY:
  89. return 4;
  90. default:
  91. return 1;
  92. }
  93. }
  94. [Tooltip("The interval in seconds at which to check this detector's conditions.")]
  95. public float Period = 0.1f;
  96. [AutoFind(AutoFindLocations.Parents)]
  97. [Tooltip("The hand model to watch. Set automatically if detector is on a hand.")]
  98. public IHandModel HandModel;
  99. [Tooltip("The finger to observe.")]
  100. public Finger.FingerType FingerName = Finger.FingerType.TYPE_INDEX;
  101. [Tooltip("The target direction.")]
  102. public Vector3 PointingDirection = Vector3.forward;
  103. [Tooltip("How to treat the target direction.")]
  104. public PointingType PointingType = PointingType.RelativeToHorizon;
  105. [Tooltip("A target object(optional). Use PointingType.AtTarget")]
  106. public Transform TargetObject;
  107. [Tooltip("The angle in degrees from the target direction at which to turn on.")]
  108. [Range(0f, 360f)]
  109. public float OnAngle = 15f;
  110. [Tooltip("The angle in degrees from the target direction at which to turn off.")]
  111. [Range(0f, 360f)]
  112. public float OffAngle = 25f;
  113. private IEnumerator watcherCoroutine;
  114. }
  115. }