在Unity的AssetStore官方商店下载Kinect v2 Examples案例包,参考KinectDemos/GestureDemo这个文件夹下的例子。
自定义一个类,实现KinectGestures.GestureListenerInterface接口。参考案例中的CubeGestureListener中的用法。下面演示监听SwipeLeft向左划,SwipeRight向右划,SwipeUp向上划的手势Gesture。其中包含了一些修改界面UI显示当前手势状态等功能,如不需要可以去掉(主要是用来调试)。
usingUnityEngine; usingSystem.Collections; usingSystem; //using Windows.Kinect; public classPeopleGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface { [Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")] public int playerIndex = 0; [Tooltip("GUI-Text to display gesture-listener messages and gesture information.")] publicGUIText gestureInfo; //singleton instance of the class private static PeopleGestureListener instance = null; //internal variables to track if progress message has been displayed private boolprogressDisplayed; private floatprogressGestureTime; //whether the needed gesture has been detected or not private boolswipeLeft; private boolswipeRight; private boolswipeUp; /// <summary> ///Gets the singleton CubeGestureListener instance. /// </summary> /// <value>The CubeGestureListener instance.</value> public staticPeopleGestureListener Instance { get { returninstance; } } /// <summary> ///Determines whether swipe left is detected. /// </summary> /// <returns><c>true</c>if swipe left is detected; otherwise, <c>false</c>.</returns> public boolIsSwipeLeft() { if(swipeLeft) { swipeLeft = false; return true; } return false; } /// <summary> ///Determines whether swipe right is detected. /// </summary> /// <returns><c>true</c>if swipe right is detected; otherwise, <c>false</c>.</returns> public boolIsSwipeRight() { if(swipeRight) { swipeRight = false; return true; } return false; } /// <summary> ///Determines whether swipe up is detected. /// </summary> /// <returns><c>true</c>if swipe up is detected; otherwise, <c>false</c>.</returns> public boolIsSwipeUp() { if(swipeUp) { swipeUp = false; return true; } return false; } /// <summary> ///Invoked when a new user is detected. Here you can start gesture tracking by invoking KinectManager.DetectGesture()-function. /// </summary> /// <param name="userId">User ID</param> /// <param name="userIndex">User index</param> public void UserDetected(long userId, intuserIndex) { //the gestures are allowed for the primary user only KinectManager manager =KinectManager.Instance; if(!manager || (userIndex !=playerIndex)) return; //detect these user specific gestures manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft); manager.DetectGesture(userId, KinectGestures.Gestures.SwipeRight); manager.DetectGesture(userId, KinectGestures.Gestures.SwipeUp); if(gestureInfo != null) { gestureInfo.text = "Swipe left, right or up to change the slides."; } } /// <summary> ///Invoked when a user gets lost. All tracked gestures for this user are cleared automatically. /// </summary> /// <param name="userId">User ID</param> /// <param name="userIndex">User index</param> public void UserLost(long userId, intuserIndex) { //the gestures are allowed for the primary user only if(userIndex !=playerIndex) return; if(gestureInfo != null) { gestureInfo.text = string.Empty; } } /// <summary> ///Invoked when a gesture is in progress. /// </summary> /// <param name="userId">User ID</param> /// <param name="userIndex">User index</param> /// <param name="gesture">Gesture type</param> /// <param name="progress">Gesture progress [0..1]</param> /// <param name="joint">Joint type</param> /// <param name="screenPos">Normalized viewport position</param> public void GestureInProgress(long userId, intuserIndex, KinectGestures.Gestures gesture, floatprogress, KinectInterop.JointType joint, Vector3 screenPos) { //the gestures are allowed for the primary user only if(userIndex !=playerIndex) return; if((gesture == KinectGestures.Gestures.ZoomOut || gesture == KinectGestures.Gestures.ZoomIn) && progress > 0.5f) { if(gestureInfo != null) { string sGestureText = string.Format ("{0} - {1:F0}%", gesture, screenPos.z *100f); gestureInfo.text =sGestureText; progressDisplayed = true; progressGestureTime =Time.realtimeSinceStartup; } } else if((gesture == KinectGestures.Gestures.Wheel || gesture == KinectGestures.Gestures.LeanLeft || gesture == KinectGestures.Gestures.LeanRight) && progress > 0.5f) { if(gestureInfo != null) { string sGestureText = string.Format ("{0} - {1:F0} degrees", gesture, screenPos.z); gestureInfo.text =sGestureText; progressDisplayed = true; progressGestureTime =Time.realtimeSinceStartup; } } else if(gesture == KinectGestures.Gestures.Run && progress > 0.5f) { if(gestureInfo != null) { string sGestureText = string.Format ("{0} - progress: {1:F0}%", gesture, progress * 100); gestureInfo.text =sGestureText; progressDisplayed = true; progressGestureTime =Time.realtimeSinceStartup; } } } /// <summary> ///Invoked if a gesture is completed. /// </summary> /// <returns>true</returns> /// <c>false</c> /// <param name="userId">User ID</param> /// <param name="userIndex">User index</param> /// <param name="gesture">Gesture type</param> /// <param name="joint">Joint type</param> /// <param name="screenPos">Normalized viewport position</param> public bool GestureCompleted (long userId, intuserIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint, Vector3 screenPos) { //the gestures are allowed for the primary user only if(userIndex !=playerIndex) return false; if(gestureInfo != null) { string sGestureText = gesture + "detected"; gestureInfo.text =sGestureText; } if(gesture ==KinectGestures.Gestures.SwipeLeft) swipeLeft = true; else if(gesture ==KinectGestures.Gestures.SwipeRight) swipeRight = true; else if(gesture ==KinectGestures.Gestures.SwipeUp) swipeUp = true; return true; } /// <summary> ///Invoked if a gesture is cancelled. /// </summary> /// <returns>true</returns> /// <c>false</c> /// <param name="userId">User ID</param> /// <param name="userIndex">User index</param> /// <param name="gesture">Gesture type</param> /// <param name="joint">Joint type</param> public bool GestureCancelled (long userId, intuserIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint) { //the gestures are allowed for the primary user only if(userIndex !=playerIndex) return false; if(progressDisplayed) { progressDisplayed = false; if(gestureInfo != null) { gestureInfo.text =String.Empty; } } return true; } voidAwake() { instance = this; } voidUpdate() { if(progressDisplayed && ((Time.realtimeSinceStartup - progressGestureTime) >2f)) { progressDisplayed = false; gestureInfo.text =String.Empty; Debug.Log("Forced progress to end."); } } }
调用方法:其他脚本获取该脚本的实例,然后通过IsSwipeLeft()等方法获取手势识别结果即可。
PeopleGestureListener gestureListener =PeopleGestureListener.Instance; if(gestureListener.IsSwipeLeft()) { //do something }
坑点:该脚本需要被挂在Kienct Manager脚本所在的游戏物体身上!
新手建议:如果自己写的GestureListener类 (实现KinectGestures.GestureListenerInterface接口)无论怎么测都不能识别出手势的话,可以复制KinectDemos/GestureDemo下面的例子场景(如KinectGesturesDemo1.unity),先实现能识别出手势了再根据自己的需求删改一下代码!
参考: