using System; using System.Collections; using Leap.Unity.Attributes; using UnityEngine; namespace Leap.Unity { public class FingerDirectionDetector : Detector { private void OnValidate() { if (this.OffAngle < this.OnAngle) { this.OffAngle = this.OnAngle; } } private void Awake() { this.watcherCoroutine = this.fingerPointingWatcher(); } private void OnEnable() { base.StartCoroutine(this.watcherCoroutine); } private void OnDisable() { base.StopCoroutine(this.watcherCoroutine); this.Deactivate(); } private IEnumerator fingerPointingWatcher() { int selectedFinger = this.selectedFingerOrdinal(); for (;;) { if (this.HandModel != null) { Hand hand = this.HandModel.GetLeapHand(); if (hand != null) { Vector3 targetDirection = this.selectedDirection(hand.Fingers[selectedFinger].TipPosition.ToVector3()); Vector3 fingerDirection = hand.Fingers[selectedFinger].Bone(Bone.BoneType.TYPE_DISTAL).Direction.ToVector3(); float num = Vector3.Angle(fingerDirection, targetDirection); if (this.HandModel.IsTracked && num <= this.OnAngle) { this.Activate(); } else if (!this.HandModel.IsTracked || num >= this.OffAngle) { this.Deactivate(); } } } yield return new WaitForSeconds(this.Period); } yield break; } private Vector3 selectedDirection(Vector3 tipPosition) { switch (this.PointingType) { case PointingType.RelativeToCamera: return Camera.main.transform.TransformDirection(this.PointingDirection); case PointingType.RelativeToHorizon: { float y = Camera.main.transform.rotation.eulerAngles.y; Quaternion rotation = Quaternion.AngleAxis(y, Vector3.up); return rotation * this.PointingDirection; } case PointingType.RelativeToWorld: return this.PointingDirection; case PointingType.AtTarget: return this.TargetObject.position - tipPosition; default: return this.PointingDirection; } } private int selectedFingerOrdinal() { switch (this.FingerName) { case Finger.FingerType.TYPE_THUMB: return 0; case Finger.FingerType.TYPE_INDEX: return 1; case Finger.FingerType.TYPE_MIDDLE: return 2; case Finger.FingerType.TYPE_RING: return 3; case Finger.FingerType.TYPE_PINKY: return 4; default: return 1; } } [Tooltip("The interval in seconds at which to check this detector's conditions.")] public float Period = 0.1f; [AutoFind(AutoFindLocations.Parents)] [Tooltip("The hand model to watch. Set automatically if detector is on a hand.")] public IHandModel HandModel; [Tooltip("The finger to observe.")] public Finger.FingerType FingerName = Finger.FingerType.TYPE_INDEX; [Tooltip("The target direction.")] public Vector3 PointingDirection = Vector3.forward; [Tooltip("How to treat the target direction.")] public PointingType PointingType = PointingType.RelativeToHorizon; [Tooltip("A target object(optional). Use PointingType.AtTarget")] public Transform TargetObject; [Tooltip("The angle in degrees from the target direction at which to turn on.")] [Range(0f, 360f)] public float OnAngle = 15f; [Tooltip("The angle in degrees from the target direction at which to turn off.")] [Range(0f, 360f)] public float OffAngle = 25f; private IEnumerator watcherCoroutine; } }