准备

首先,你需要准备的东西

  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. 具体函数的功能什么的在帮助文档里面有。先看关于手势识别的帮助文档,然后在来看下面的代码

    代码:

     using UnityEngine;
    using System; public class MyGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
    {
    [Tooltip("GUI-Text to display gesture-listener messages and gesture information.")]
    public GUIText gestureInfo; // private bool to track if progress message has been displayed
    private bool progressDisplayed;
    private float progressGestureTime; /*
    * 当识别到用户时调用该函数
    */
    public void UserDetected(long userId, int userIndex)
    {
    // as an example - detect these user specific gestures
    KinectManager manager = KinectManager.Instance;
    //manager.DetectGesture(userId, KinectGestures.Gestures.Jump);
    //manager.DetectGesture(userId, KinectGestures.Gestures.Squat);
    //manager.DetectGesture(userId, KinectGestures.Gestures.LeanLeft);
    //manager.DetectGesture(userId, KinectGestures.Gestures.LeanRight);
    //manager.DetectGesture(userId, KinectGestures.Gestures.RaiseLeftHand);
    //manager.DetectGesture(userId, KinectGestures.Gestures.RaiseRightHand); manager.DetectGesture(userId, KinectGestures.Gestures.Run); if (gestureInfo != null)
    {
    gestureInfo.GetComponent<GUIText>().text = "Swipe, Jump, Squat or Lean.";
    }
    Debug.Log("发现用户");
    } /*
    * 当失去用户时出发
    */
    public void UserLost(long userId, int userIndex)
    {
    if (gestureInfo != null)
    {
    gestureInfo.GetComponent<GUIText>().text = string.Empty;
    }
    Debug.Log("失去用户");
    } /// <summary>
    /// Invoked when a gesture is in progress.
    /// </summary>
    /// <param name="userId">被识别者的id</param>
    /// <param name="userIndex">被识别者的序号</param>
    /// <param name="gesture">手势类型</param>
    /// <param name="progress">手势识别的进度,可以认为是相似度。范围是[0,1]</param>
    /// <param name="joint">关节类型</param>
    /// <param name="screenPos">视图坐标的单位向量</param>
    public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture,
    float progress, KinectInterop.JointType joint, Vector3 screenPos)
    {
    /*
    * 主要将一些需要动态监测的手势放在这个函数下
    * 比如说缩放、滚轮都是依据你两手之间的距离来判断应该缩放或旋转多少度
    */ //监测缩放,如果相似度大于50%
    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.GetComponent<GUIText>().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.GetComponent<GUIText>().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 * );
    gestureInfo.GetComponent<GUIText>().text = sGestureText; progressDisplayed = true;
    progressGestureTime = Time.realtimeSinceStartup;
    }
    }
    } /// <summary>
    /// 当一个手势识别完成后被调用
    /// </summary>
    /// <returns>true</returns>
    /// <c>false</c>
    /// <param name="userId">被识别者的ID</param>
    /// <param name="userIndex">被识别者的序号</param>
    /// <param name="gesture">被识别到的手势类型</param>
    /// <param name="joint">被识别到的关节类型</param>
    /// <param name="screenPos">视图坐标的单位向量</param>
    public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture,
    KinectInterop.JointType joint, Vector3 screenPos)
    {
    if (progressDisplayed)
    return true; string sGestureText = gesture + " detected";
    if (gestureInfo != null)
    {
    gestureInfo.GetComponent<GUIText>().text = sGestureText;
    } return true;
    } //参数同上,在手势被取消的时候调用
    public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture,
    KinectInterop.JointType joint)
    {
    if (progressDisplayed)
    {
    progressDisplayed = false; if (gestureInfo != null)
    {
    gestureInfo.GetComponent<GUIText>().text = String.Empty;
    }
    } return true;
    } public void Update()
    {
    if (progressDisplayed && ((Time.realtimeSinceStartup - progressGestureTime) > 2f))
    {
    progressDisplayed = false; if (gestureInfo != null)
    {
    gestureInfo.GetComponent<GUIText>().text = String.Empty;
    } Debug.Log("Forced progress to end.");
    }
    } }
  5. 这个代码我直接用的官方的实例修改的。为了显示出效果,可以新建一个空物体,添加上GUI Text组件,让他显示识别的效果

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

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

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

继续入门

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

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

    <( ̄︶ ̄)>

  4.  using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using System; public class MyGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
    {
    public Text gestureInfo;
    private bool state = false;//识别状态,0表示未识别,1表示已识别
    public float intervalTime = 5.0f;
    private bool intervalBegin = false;
    private int quiet = ;
    private float quiettime = 5.0f;
    public enum 手势
    {
    剪刀,
    石头,

    }
    private 手势 RandomShoushi()
    {
    System.Random ran = new System.Random();
    int randomnum = ran.Next(, );
    return (手势)randomnum;
    } private string getInfo(KinectInterop.HandState show, 手势 shoushi)
    {
    string info = string.Empty;
    switch (show)
    {
    case KinectInterop.HandState.Closed:info= "你出的是石头\n";
    break;
    case KinectInterop.HandState.Lasso: info = "你出的是剪刀\n";
    break;
    case KinectInterop.HandState.Open:info= "你出的是布\n";
    break;
    default: info = "请出招...\n";
    return info;
    } switch (shoushi)
    {
    case 手势.石头:
    info += "电脑出的是石头\n";
    break;
    case 手势.剪刀:
    info += "电脑出的是剪刀\n";
    break;
    case 手势.布:
    info += "电脑出的是布\n";
    break;
    }
    int res = contrast(show, shoushi);
    if (res == )
    {
    info += "哈哈哈,你赢了\n";
    }
    else if (res == -)
    {
    info += "哈哈哈,你输了\n";
    }else if (res == )
    {
    info += "哈哈哈,平手";
    }
    else
    {
    info += "你的手势未识别";
    } state = true;//识别完成
    return info; } private int contrast(KinectInterop.HandState show,手势 shoushi)
    {
    int rssult = ; switch (show)
    {
    case KinectInterop.HandState.Closed:
    switch (shoushi)
    {
    case 手势.石头:rssult = ;
    break;
    case 手势.剪刀:
    rssult = ;
    break;
    case 手势.布:
    rssult = -;
    break;
    }
    break;
    case KinectInterop.HandState.Lasso:
    switch (shoushi)
    {
    case 手势.石头:
    rssult = -;
    break;
    case 手势.剪刀:
    rssult = ;
    break;
    case 手势.布:
    rssult = ;
    break;
    }
    break;
    case KinectInterop.HandState.Open:
    switch (shoushi)
    {
    case 手势.石头:
    rssult = ;
    break;
    case 手势.剪刀:
    rssult = -;
    break;
    case 手势.布:
    rssult = ;
    break;
    }
    break;
    default:rssult = ;
    break;
    }
    return rssult;
    }
    void Update()
    { if (intervalBegin)
    {
    if (intervalTime > )
    {
    intervalTime -= Time.deltaTime;
    }
    else
    {
    intervalBegin = false;
    intervalTime = 5.0f;
    state = false;
    }
    } if (!state)
    {
    KinectManager _manager = KinectManager.Instance;
    long userid = _manager.GetUserIdByIndex();
    gestureInfo.text=getInfo(_manager.GetRightHandState(userid), RandomShoushi());
    }
    if (quiet==)
    {
    gestureInfo.text = "再右挥一次就不跟你玩了...";
    if (quiet == )
    {
    Debug.Log("退出");
    Application.Quit(); }
    if (quiettime < )
    {
    quiet = ;
    quiettime = 5.0f;
    gestureInfo.text = "请出招...";
    }
    else
    {
    quiettime -= Time.deltaTime;
    }
    }
    } public void UserDetected(long userId, int userIndex)
    {
    //throw new NotImplementedException();
    KinectManager manager = KinectManager.Instance;
    manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft);
    } public void UserLost(long userId, int userIndex)
    {
    //throw new NotImplementedException();
    } public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture, float progress, KinectInterop.JointType joint, Vector3 screenPos)
    {
    //throw new NotImplementedException();
    } public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint, Vector3 screenPos)
    {
    //throw new NotImplementedException();
    if (gesture== KinectGestures.Gestures.SwipeLeft)
    {
    intervalBegin = true;
    gestureInfo.text = "准备出招...";
    }
    if (gesture == KinectGestures.Gestures.SwipeRight)
    {
    quiet++;
    }
    return true;
    } public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint)
    {
    //throw new NotImplementedException();
    return true;
    }
    }

Unity使用Kinect初级教程的更多相关文章

  1. Siki_Unity_1-6_C#编程初级教程(未学)

    Unity 1-6 C#编程初级教程 任务1:C#和.Net框架 C#是.Net里的一个成分 2002年微软发布第一个.Net框架(多平台,行业标准,安全性) .Net框架 IDE编程工具 --产生- ...

  2. Python图像处理库:Pillow 初级教程

    Python图像处理库:Pillow 初级教程 2014-09-14 翻译 http://pillow.readthedocs.org/en/latest/handbook/tutorial.html ...

  3. shellKali Linux Web 渗透测试— 初级教程(第三课)

    shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...

  4. Mac OS X Terminal 101:终端使用初级教程

    Mac OS X Terminal 101:终端使用初级教程 发表于 2012 年 7 月 29 日 由 Renfei Song | 文章目录 1 为什么要使用命令行/如何开启命令行? 2 初识Com ...

  5. Coding 初级教程(二)——上传已有项目

    Coding 初级教程(二)——上传已有项目 [摘要:方针读者 :已具有 Coding.net 的账号. 本文首要先容若何把项目上传到 Coding.net 上. 分两种环境,一种是项目已归入到 gi ...

  6. [初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY

    [初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY 发布者:sqqdugdu 时间:10-06 阅读数:2117 测试环境:RHEL 6.1,SecureCRT 5 ...

  7. Window服务初级教程以及log4net配置文件初始化

    Window服务初级教程:http://www.jb51.net/article/48987.htm 另外,配置log4net这个日志功能的时候需要初始化,不然会报没有初始化的错误,而且初始化的节点应 ...

  8. 《自学C语言》初级教程 - 目录

    我现在打算出一个C语言学习教程,目的是为了让初学者能够很容易和更深刻地理解C语言. 你可能有这样的疑问,网上不是有很多的初级教程吗,我需要这个吗?我的回答是:网上的C语言教程讲得不够全面,而且许多的初 ...

  9. Unity 4.3 2D 教程:新手上路

    这篇文章译自 Christopher LaPollo 先生的 Unity 4.3 2D 教程的第一部分 Unity 4.3 2D Tutorial: Getting Started 感谢这套优秀教程的 ...

随机推荐

  1. 【Linux】Centos部署MySQL

    将CentOS部署MySQL需要本地配置环境.本地编译MySQL,耗时较长的情况,优化为编译成型MySQL并打包,推送并按配置部署. 首先需要在一台机器配置好环境,搭个YUM源,并将所需要的包取出备用 ...

  2. CSS优先级算法是如何计算?

    CSS的specificity特性或非凡性,它是一个衡量css优先级的一个标准, 既然的标准就有判定规定和计算方式,specificity用一个四位数来表示, 更像四级从左到右,左的最大级,一级大于一 ...

  3. 解决Linux中遇到No such device

    虚拟机备份转移后,网络启动异常,提示“SIOCSIFADDR: No such device” he problem lies in the fact that ethernet MAC addres ...

  4. iOS中UIKit——UIFont得到iOS设备上的系统字体

    for (NSString *fontFamily  in [UIFont familyNames]) { NSLog(@"字体家族是:%@",fontFamily); for(N ...

  5. js实现touch移动触屏滑动事件

    在开始描述touch事件之前,需要先描述一下多触式系统中特有的touch对象(android和iOS乃至nokia最新的meego系统都模拟了类 似的对象).这个对象封装一次屏幕触摸,一般来自于手指. ...

  6. 年薪10W和100w的人差距在哪?

    12年前,我直升了硕士,在家闲得慌,去一家香港的婴幼儿杂志全职实习,每天早上8点上班,下午5点下班,一个月我负责20p左右的内容,实习工资800元. 公司很小,没有办公室政治,大家都很松散,上班打打游 ...

  7. mysql数据库开发规范

    对规范的遵守可用二八原则,不要教条.为满足实际需求 可忽视部分规范. 1.索引规范 *目标 |--利用最小的索引成本找到需要的行记录 *原则 |--做前缀匹配 |--选择区分度高的列做前缀索引列 |- ...

  8. prettyprint

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. java软件包的访问权限和继承

    public:公共权限,可以修饰类.成员变量和成员函数,不论是否在同一个包中均可自由访问 package wang; //当一个类的权限为public时,类名必须和文件名相同 public class ...

  10. Mysql允许外网接入

    首先你可以为mysql创建一个账户,或者为root用户接入数据库. 授权用户指定所有主机以指定用户连接服务器 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDE ...