using UnityEngine; using System.Collections; public class HandsWave : MonoBehaviour { public GameObject leftHand; public GameObject rightHand; public GameObject rightElbow; public KinectPointController kpc; private SkeletonWrapper sw; private Vector3 leftPos; private Vector3 rightPos; private Vector3 elbowRightPos; int player = 0; private const int WAVE_MOVEMENT_TIMEOUT = 5000; private const float WAVE_THRESHOLD = 0.1f; private const int REQUIRED_ITERATIONS = 1; private Kinect.KinectInterface kinect; public DeviceOrEmulator devOrEmu; WaveGestureTracker tracker = new WaveGestureTracker(); ////////////////////////////////////////////////////////////////////////// private enum WavePosition { None = 0, Left = 1, Right = 2, Neutral = 3 } private enum WaveGestureState { None = 0, Success = 1, Failure = 2, InProgress = 3 } private struct WaveGestureTracker { public int IterationCount; public WaveGestureState State; public long Timestamp; public WavePosition StartPosition; public WavePosition CurrentPosition; public void UpdateState(WaveGestureState state, long timestamp) { State = state; Timestamp = timestamp; } public void Reset() { IterationCount = 0; State = WaveGestureState.None; Timestamp = 0; StartPosition = WavePosition.None; CurrentPosition = WavePosition.None; } public void UpdatePosition(WavePosition position, long timestamp) { if (CurrentPosition != position) { if (position == WavePosition.Left || position == WavePosition.Right) { if (State != WaveGestureState.InProgress) { State = WaveGestureState.InProgress; IterationCount = 0; StartPosition = position; } IterationCount++; } CurrentPosition = position; Timestamp = timestamp; } } } ////////////////////////////////////////////////////////////////////////// // Use this for initialization void Start() { sw = kpc.sw; kinect = devOrEmu.getKinect(); StartCoroutine(LoopCheck()); } // Update is called once per frame void Update () { } IEnumerator LoopCheck() { while (true) { CheckHands(); yield return new WaitForSeconds(0.1f); } } void CheckHands() { leftPos = leftHand.transform.position; rightPos = rightHand.transform.position; elbowRightPos = rightElbow.transform.position; long timestamp = kinect.getSkeleton().liTimeStamp; if (sw.boneState[player, (int)Kinect.NuiSkeletonPositionIndex.HandLeft] != Kinect.NuiSkeletonPositionTrackingState.NotTracked || sw.boneState[player, (int)Kinect.NuiSkeletonPositionIndex.HandRight] != Kinect.NuiSkeletonPositionTrackingState.NotTracked) { if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp) { tracker.UpdateState(WaveGestureState.Failure, timestamp); Debug.Log("Fail!"); } else if (leftPos.x < rightPos.x && rightPos.y > elbowRightPos.y)// 双手未交叉 { //使用 (0, 0) 作为屏幕的中心. 从用户的视角看, X轴左负右正. if (rightPos.x <= elbowRightPos.x - WAVE_THRESHOLD) { tracker.UpdatePosition(WavePosition.Left, timestamp); } else if (rightPos.x >= elbowRightPos.x + WAVE_THRESHOLD) { tracker.UpdatePosition(WavePosition.Right, timestamp); } else { tracker.UpdatePosition(WavePosition.Neutral, timestamp); } if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS) { tracker.UpdateState(WaveGestureState.Success, timestamp); Debug.Log("Success" + tracker.CurrentPosition); //if (GestureDetected != null) //{ // GestureDetected(this, new EventArgs()); //} } } else { if (tracker.State == WaveGestureState.InProgress) { tracker.UpdateState(WaveGestureState.Failure, timestamp); System.Diagnostics.Debug.WriteLine("Fail!"); } else { tracker.Reset(); } } } else { tracker.Reset(); //Debug.Log("NotTracked"); } } }