【Unity/Kinect】手势识别Gesture

摘要:
参考案例中的CubeGestureListener中的用法。下面演示监听SwipeLeft向左划,SwipeRight向右划,SwipeUp向上划的手势Gesture。其中包含了一些修改界面UI显示当前手势状态等功能,如不需要可以去掉。

在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),先实现能识别出手势了再根据自己的需求删改一下代码!

【Unity/Kinect】手势识别Gesture第1张


参考:

免责声明:文章转载自《【Unity/Kinect】手势识别Gesture》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java注解--实现动态数据源切换Less安装与使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

unity材质球贴图滚动

using System.Collections; using System.Collections.Generic; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { //滚动速度 public float HorSpeed = 1.0f;...

Kinect 深度测量原理

和其他摄像机一样,近红外摄像机也有视场。Kinect摄像机的视野是有限的,如下图所示:      如图,红外摄像机的视场是金字塔形状的。离摄像机远的物体比近的物体拥有更大的视场横截面积。这意味着影像的高度和宽度,比如640X480和摄像机视场的物理位置并不一一对应。但是每个像素的深度值是和视场中物体离摄像机的距离是对应的。深度帧数据中,每个像素占16位,...

Unity添加多个可视镜头Preview功能(一)

打算写这样一个工具,可用于影片镜头调节,房产漫游的可视化,建立多个可视镜头,可以动态调整各个镜头的位置和旋转方向,同时,还能在类似于Camera 的Preview这样的小窗口中查看该镜头(在小窗口中点击鼠标左键并拖拽能调节镜头的旋转轴向),示意图如下: 首先,第一步:创建一个脚本,公开两个参数(目前功能还有待丰富,后续更新...) 第二步:创建一个E...

Unity表面着色器

表面着色器和之前无光照着色器不同,其中没有顶点着色器和片元着色器,而增加了光照函数; 接下写了一个求两个贴图的光照效果 两个贴图做插值运算: Shader "Custom/SurfaceShader" { Properties { _Color ("Color", Color) = (1,1,1,1)...

Unity资源Assetbundle

转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details/17652021 如果这篇文章对你有帮助,敬请关注作者《Unity手游之路》系列教程。 在手游的运营过程中...

【整理】unity3d优化总结篇

对项目优化有很多,如:mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等,现在继续补上,该内容为本人经验以及网上收集整理,希望大家有更好的优化方法,能够继续跟帖,一起探讨,共同进步。优化:1. 更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,每家的GPU支持不同的压缩格式,但他们都...