zoukankan      html  css  js  c++  java
  • 【Unity/Kinect】手势识别Gesture

    在Unity的AssetStore官方商店下载Kinect v2 Examples案例包,参考KinectDemos/GestureDemo这个文件夹下的例子。

    自定义一个类,实现KinectGestures.GestureListenerInterface接口。参考案例中的CubeGestureListener中的用法。下面演示监听SwipeLeft向左划,SwipeRight向右划,SwipeUp向上划的手势Gesture。其中包含了一些修改界面UI显示当前手势状态等功能,如不需要可以去掉(主要是用来调试)。

    using UnityEngine;
    using System.Collections;
    using System;
    //using Windows.Kinect;
    
    public class PeopleGestureListener : 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.")]
        public GUIText gestureInfo;
    
        // singleton instance of the class
        private static PeopleGestureListener instance = null;
    
        // internal variables to track if progress message has been displayed
        private bool progressDisplayed;
        private float progressGestureTime;
    
        // whether the needed gesture has been detected or not
        private bool swipeLeft;
        private bool swipeRight;
        private bool swipeUp;
        
    
        /// <summary>
        /// Gets the singleton CubeGestureListener instance.
        /// </summary>
        /// <value>The CubeGestureListener instance.</value>
        public static PeopleGestureListener Instance
        {
            get
            {
                return instance;
            }
        }
        
        /// <summary>
        /// Determines whether swipe left is detected.
        /// </summary>
        /// <returns><c>true</c> if swipe left is detected; otherwise, <c>false</c>.</returns>
        public bool IsSwipeLeft()
        {
            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 bool IsSwipeRight()
        {
            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 bool IsSwipeUp()
        {
            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, int userIndex)
        {
            // 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, int userIndex)
        {
            // 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, int userIndex, KinectGestures.Gestures gesture, 
                                      float progress, 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, int userIndex, 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, int userIndex, 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;
        }
    
        
        void Awake()
        {
            instance = this;
        }
    
        void Update()
        {
            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),先实现能识别出手势了再根据自己的需求删改一下代码!


    参考:

  • 相关阅读:
    2019.6.20刷题统计
    36 线程 队列 守护线程 互斥锁 死锁 可重入锁 信号量
    35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型
    34 进程 pid ppid 并发与并行,阻塞与非阻塞 join函数 process对象 孤儿进程与僵尸进程
    33 udp 域名 进程
    32 粘包 文件传输
    31 socket客户端. 服务器 异常 语法
    30 网络编程
    29 元类 异常
    26 封装 反射 常用内置函数
  • 原文地址:https://www.cnblogs.com/guxin/p/unity-kinect-how-to-use-gesture.html
Copyright © 2011-2022 走看看