Unity使用Kinect初级教程

准备

首先,你需要准备的东西

  1. Windows 8以上系统的电脑,当然,配置不要太渣⊙︿⊙
  2. Kinect for Windows开发套件
  3. 安装好Kinect for Windows SDK,这个应该属于开发套件里的吧╮(╯▽╰)╭
  4. 安装好了Unity5.X,并且确定可以使用
  5. Kinect For Windows Wrapper。这是使用unity开发Kinect的中间插件,网上有很多种版本。但是基本都推荐卡耐基梅隆的,我这里也用的是卡耐基梅隆,版本是v2.9。2.7和2.8我都试过,但是使用总有一些问题没有在其他电脑上试过,不知道其他电脑可不可用。反正在这里推荐2.9,至少我用着没问题<( ̄︶ ̄)>。

  可以点击后面那坨云下载2.9版插件 点击下载 密码:6abd

  版本更新了,点击后面那坨云下载2.13版插件 点击下载 密码:e4uw

入门

上面如果都没有问题的话下面我们可以着手入门开发了

  1. 新建一个unity项目
  2. 导入Kinect For Windows Wrapper
  3. 导入之后可以运行一些Demo,看看我们可以拿这个Kinect做些什么

  4. 开发的第一步当然是看他的帮助文档,这里面讲述了使用的步骤

  5. 英文看不懂?我这里有一个翻译得非常粗糙的版本。点我跳过去。作为一个四级没过的能翻译成这样还要啥自行车
  6. 至此你可以把鼠标移到右上角点×关掉去看帮助文档了。懒癌患者可以继续往下浏览。但是这里我不打算讲太多,还是推荐去看文档,英文原版那个<( ̄︶ ̄)>。
  7. 好吧,继续。首先配置好你准备角色的Avatar。至于怎么配置我这里说不清楚,去看看这方面的教程,最好是视频的。下图是我在Asset Store里下载的一个角色模型。我们就用它了

  8. 把角色拖入场景,不要有Rigibody,不要有Collider,Animator里不要有Controller。因为这些可能会影响角色的动画,但我们需要角色的各个节点都能自由移动
  9. 然后把AvatarController脚本拖给角色

  10. 新建一个空物体,命名为KinectManager,然后把KinectManager脚本拖给他
  11. 然后你可以运行测试一下了,这个机器人将会同步你的动作。没错,就是这么简单(>﹏<)。至于具体的参数什么的还是去看文档。这里不多说。

     

再入门

上面我们已经能让模型反映真实人的动作了,下面来讲解一下动作识别

  1. 首先,需要把KinectGestures脚本添加到KinectManager这个物体上。
  2. 新建一个空物体,命名为GestureListener。
  3. 新建一个脚本MyGestureListener.cs。这个脚本需要继承MonoBehaviour类并且实现KinectGestures.GestureListenerInterface接口。
  4. 具体函数的功能什么的在帮助文档里面有。先看关于手势识别的帮助文档,然后在来看下面的代码

    代码:

     

      1 using UnityEngine;
      2 using System;
      3 
      4 
      5 public class MyGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
      6 {
      7     [Tooltip("GUI-Text to display gesture-listener messages and gesture information.")]
      8     public GUIText gestureInfo;
      9 
     10     // private bool to track if progress message has been displayed
     11     private bool progressDisplayed;
     12     private float progressGestureTime;
     13 
     14 
     15 
     16     /*
     17     * 当识别到用户时调用该函数
     18     */
     19     public void UserDetected(long userId, int userIndex)
     20     {
     21         // as an example - detect these user specific gestures
     22         KinectManager manager = KinectManager.Instance;
     23         //manager.DetectGesture(userId, KinectGestures.Gestures.Jump);
     24         //manager.DetectGesture(userId, KinectGestures.Gestures.Squat);
     25         //manager.DetectGesture(userId, KinectGestures.Gestures.LeanLeft);
     26         //manager.DetectGesture(userId, KinectGestures.Gestures.LeanRight);
     27         //manager.DetectGesture(userId, KinectGestures.Gestures.RaiseLeftHand);
     28         //manager.DetectGesture(userId, KinectGestures.Gestures.RaiseRightHand);
     29 
     30         manager.DetectGesture(userId, KinectGestures.Gestures.Run);
     31 
     32         if (gestureInfo != null)
     33         {
     34             gestureInfo.GetComponent<GUIText>().text = "Swipe, Jump, Squat or Lean.";
     35         }
     36         Debug.Log("发现用户");
     37     }
     38 
     39 
     40 
     41     /*
     42     * 当失去用户时出发
     43     */
     44     public void UserLost(long userId, int userIndex)
     45     {
     46         if (gestureInfo != null)
     47         {
     48             gestureInfo.GetComponent<GUIText>().text = string.Empty;
     49         }
     50         Debug.Log("失去用户");
     51     }
     52 
     53 
     54     /// <summary>
     55     /// Invoked when a gesture is in progress.
     56     /// </summary>
     57     /// <param name="userId">被识别者的id</param>
     58     /// <param name="userIndex">被识别者的序号</param>
     59     /// <param name="gesture">手势类型</param>
     60     /// <param name="progress">手势识别的进度,可以认为是相似度。范围是[0,1]</param>
     61     /// <param name="joint">关节类型</param>
     62     /// <param name="screenPos">视图坐标的单位向量</param>
     63     public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture,
     64                                   float progress, KinectInterop.JointType joint, Vector3 screenPos)
     65     {
     66         /*
     67          * 主要将一些需要动态监测的手势放在这个函数下
     68          * 比如说缩放、滚轮都是依据你两手之间的距离来判断应该缩放或旋转多少度
     69          */
     70 
     71         //监测缩放,如果相似度大于50%
     72         if ((gesture == KinectGestures.Gestures.ZoomOut || gesture == KinectGestures.Gestures.ZoomIn) && progress > 0.5f)
     73         {
     74             if (gestureInfo != null)
     75             {
     76                 string sGestureText = string.Format("{0} - {1:F0}%", gesture, screenPos.z * 100f);
     77                 gestureInfo.GetComponent<GUIText>().text = sGestureText;
     78 
     79                 progressDisplayed = true;
     80                 progressGestureTime = Time.realtimeSinceStartup;
     81             }
     82         }
     83         else if ((gesture == KinectGestures.Gestures.Wheel || gesture == KinectGestures.Gestures.LeanLeft ||
     84                  gesture == KinectGestures.Gestures.LeanRight) && progress > 0.5f)
     85         {
     86             if (gestureInfo != null)
     87             {
     88                 string sGestureText = string.Format("{0} - {1:F0} degrees", gesture, screenPos.z);
     89                 gestureInfo.GetComponent<GUIText>().text = sGestureText;
     90 
     91                 progressDisplayed = true;
     92                 progressGestureTime = Time.realtimeSinceStartup;
     93             }
     94         }
     95         else if (gesture == KinectGestures.Gestures.Run && progress > 0.5f)
     96         {
     97             if (gestureInfo != null)
     98             {
     99                 string sGestureText = string.Format("{0} - progress: {1:F0}%", gesture, progress * 100);
    100                 gestureInfo.GetComponent<GUIText>().text = sGestureText;
    101 
    102                 progressDisplayed = true;
    103                 progressGestureTime = Time.realtimeSinceStartup;
    104             }
    105         }
    106     }
    107 
    108 
    109 
    110 
    111     /// <summary>
    112     /// 当一个手势识别完成后被调用
    113     /// </summary>
    114     /// <returns>true</returns>
    115     /// <c>false</c>
    116     /// <param name="userId">被识别者的ID</param>
    117     /// <param name="userIndex">被识别者的序号</param>
    118     /// <param name="gesture">被识别到的手势类型</param>
    119     /// <param name="joint">被识别到的关节类型</param>
    120     /// <param name="screenPos">视图坐标的单位向量</param>
    121     public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture,
    122                                   KinectInterop.JointType joint, Vector3 screenPos)
    123     {
    124         if (progressDisplayed)
    125             return true;
    126 
    127         string sGestureText = gesture + " detected";
    128         if (gestureInfo != null)
    129         {
    130             gestureInfo.GetComponent<GUIText>().text = sGestureText;
    131         }
    132 
    133         return true;
    134     }
    135 
    136 
    137 
    138     //参数同上,在手势被取消的时候调用
    139     public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture,
    140                                   KinectInterop.JointType joint)
    141     {
    142         if (progressDisplayed)
    143         {
    144             progressDisplayed = false;
    145 
    146             if (gestureInfo != null)
    147             {
    148                 gestureInfo.GetComponent<GUIText>().text = String.Empty;
    149             }
    150         }
    151 
    152         return true;
    153     }
    154 
    155     public void Update()
    156     {
    157         if (progressDisplayed && ((Time.realtimeSinceStartup - progressGestureTime) > 2f))
    158         {
    159             progressDisplayed = false;
    160 
    161             if (gestureInfo != null)
    162             {
    163                 gestureInfo.GetComponent<GUIText>().text = String.Empty;
    164             }
    165 
    166             Debug.Log("Forced progress to end.");
    167         }
    168     }
    169 
    170 }

     

  5. 这个代码我直接用的官方的实例修改的。为了显示出效果,可以新建一个空物体,添加上GUI Text组件,让他显示识别的效果

  6. 好了,你可以测试一下了

 

下面来讲关于手势识别的,上面讲的手势其实是Gesture的翻译,是全身的;下面讲的手势是针对于手的

好了,咋们。。。。︿( ̄︶ ̄)

继续入门

  1. 首先要知道Kinect可以识别的手势。定义在KinectInterop.HandState这个枚举类型中

  2. 你可以通过KinectManager的GetRightHandState(long UserID)来获取用户的右手手势状态(别问我怎么获取左手→_→)
  3. 下面发一段给电脑玩剪刀石头布的代码。代码比较粗糙,不过作为学习还是阔仪滴

    <( ̄︶ ̄)>

  4.   1 using UnityEngine;
      2 using UnityEngine.UI;
      3 using System.Collections;
      4 using System;
      5 
      6 
      7 public class MyGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
      8 {
      9     public Text gestureInfo;
     10     private bool state = false;//识别状态,0表示未识别,1表示已识别
     11     public float intervalTime = 5.0f;
     12     private bool intervalBegin = false;
     13     private int quiet = 0;
     14     private float quiettime = 5.0f;
     15     public enum 手势
     16     {
     17         剪刀,
     18         石头,
     19  20     }
     21     private 手势 RandomShoushi()
     22     {
     23         System.Random ran = new System.Random();
     24         int randomnum = ran.Next(0, 2);
     25         return (手势)randomnum;
     26     }
     27 
     28     private string getInfo(KinectInterop.HandState show, 手势 shoushi)
     29     {
     30         string info = string.Empty;
     31         switch (show)
     32         {
     33             case KinectInterop.HandState.Closed:info= "你出的是石头\n";
     34                 break;
     35             case KinectInterop.HandState.Lasso: info = "你出的是剪刀\n";
     36                 break;
     37             case KinectInterop.HandState.Open:info= "你出的是布\n";
     38                 break;
     39             default: info = "请出招...\n";
     40                 return info;
     41         }
     42 
     43         switch (shoushi)
     44         {
     45             case 手势.石头:
     46                 info += "电脑出的是石头\n";
     47                 break;
     48             case 手势.剪刀:
     49                 info += "电脑出的是剪刀\n";
     50                 break;
     51             case 手势.布:
     52                 info += "电脑出的是布\n";
     53                 break;
     54         }
     55         int res = contrast(show, shoushi);
     56         if (res == 1)
     57         {
     58             info += "哈哈哈,你赢了\n";
     59         }
     60         else if (res == -1)
     61         {
     62             info += "哈哈哈,你输了\n";
     63         }else if (res == 0)
     64         {
     65             info += "哈哈哈,平手";
     66         }
     67         else
     68         {
     69             info += "你的手势未识别";
     70         }
     71 
     72         state = true;//识别完成
     73         return info;
     74 
     75     }
     76 
     77 
     78     private int contrast(KinectInterop.HandState show,手势 shoushi)
     79     {
     80         int rssult = 0;
     81 
     82         switch (show)
     83         {
     84             case KinectInterop.HandState.Closed:
     85                 switch (shoushi)
     86                 {
     87                     case 手势.石头:rssult = 0;
     88                         break;
     89                     case 手势.剪刀:
     90                         rssult = 1;
     91                         break;
     92                     case 手势.布:
     93                         rssult = -1;
     94                         break;
     95                 }
     96                 break;
     97             case KinectInterop.HandState.Lasso:
     98                 switch (shoushi)
     99                 {
    100                     case 手势.石头:
    101                         rssult = -1;
    102                         break;
    103                     case 手势.剪刀:
    104                         rssult = 0;
    105                         break;
    106                     case 手势.布:
    107                         rssult = 1;
    108                         break;
    109                 }
    110                 break;
    111             case KinectInterop.HandState.Open:
    112                 switch (shoushi)
    113                 {
    114                     case 手势.石头:
    115                         rssult = 1;
    116                         break;
    117                     case 手势.剪刀:
    118                         rssult = -1;
    119                         break;
    120                     case 手势.布:
    121                         rssult = 0;
    122                         break;
    123                 }
    124                 break;
    125             default:rssult = 10;
    126                 break;
    127         }
    128         return rssult;
    129     }
    130     void Update()
    131     {
    132         
    133         if (intervalBegin)
    134         {
    135             if (intervalTime > 0)
    136             {
    137                 intervalTime -= Time.deltaTime;
    138             }
    139             else
    140             {
    141                 intervalBegin = false;
    142                 intervalTime = 5.0f;
    143                 state = false;
    144             }
    145         }
    146         
    147         if (!state)
    148         {
    149             KinectManager _manager = KinectManager.Instance;
    150             long userid = _manager.GetUserIdByIndex(0);
    151             gestureInfo.text=getInfo(_manager.GetRightHandState(userid), RandomShoushi());
    152         }
    153         if (quiet==1)
    154         {
    155             gestureInfo.text = "再右挥一次就不跟你玩了...";
    156             if (quiet == 2)
    157             {
    158                 Debug.Log("退出");
    159                 Application.Quit();
    160                 
    161             }
    162             if (quiettime < 0)
    163             {
    164                 quiet = 0;
    165                 quiettime = 5.0f;
    166                 gestureInfo.text = "请出招...";
    167             }
    168             else
    169             {
    170                 quiettime -= Time.deltaTime;
    171             }
    172         }
    173     }
    174 
    175     public void UserDetected(long userId, int userIndex)
    176     {
    177         //throw new NotImplementedException();
    178         KinectManager manager = KinectManager.Instance;
    179         manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft);
    180     }
    181 
    182     public void UserLost(long userId, int userIndex)
    183     {
    184         //throw new NotImplementedException();
    185     }
    186 
    187     public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture, float progress, KinectInterop.JointType joint, Vector3 screenPos)
    188     {
    189         //throw new NotImplementedException();
    190     }
    191 
    192     public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint, Vector3 screenPos)
    193     {
    194         //throw new NotImplementedException();
    195         if (gesture== KinectGestures.Gestures.SwipeLeft)
    196         {
    197             intervalBegin = true;
    198             gestureInfo.text = "准备出招...";
    199         }
    200         if (gesture == KinectGestures.Gestures.SwipeRight)
    201         {
    202             quiet++;
    203         }
    204         return true;
    205     }
    206 
    207     public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint)
    208     {
    209         //throw new NotImplementedException();
    210         return true;
    211     }
    212 }

     


     

     

posted @ 2016-12-20 17:09  Zack__zhang  阅读(29546)  评论(6编辑  收藏  举报