Unity使用Kinect初级教程
准备
首先,你需要准备的东西
- Windows 8以上系统的电脑,当然,配置不要太渣⊙︿⊙
- Kinect for Windows开发套件
- 安装好Kinect for Windows SDK,这个应该属于开发套件里的吧╮(╯▽╰)╭
- 安装好了Unity5.X,并且确定可以使用
- Kinect For Windows Wrapper。这是使用unity开发Kinect的中间插件,网上有很多种版本。但是基本都推荐卡耐基梅隆的,我这里也用的是卡耐基梅隆,版本是v2.9。2.7和2.8我都试过,但是使用总有一些问题没有在其他电脑上试过,不知道其他电脑可不可用。反正在这里推荐2.9,至少我用着没问题<( ̄︶ ̄)>。
可以点击后面那坨云下载2.9版插件 密码:6abd
版本更新了,点击后面那坨云下载2.13版插件 密码:e4uw
入门
上面如果都没有问题的话下面我们可以着手入门开发了
- 新建一个unity项目
- 导入Kinect For Windows Wrapper
- 导入之后可以运行一些Demo,看看我们可以拿这个Kinect做些什么
- 开发的第一步当然是看他的帮助文档,这里面讲述了使用的步骤
- 英文看不懂?我这里有一个翻译得非常粗糙的版本。点我跳过去。作为一个四级没过的能翻译成这样还要啥自行车
- 至此你可以把鼠标移到右上角点×关掉去看帮助文档了。懒癌患者可以继续往下浏览。但是这里我不打算讲太多,还是推荐去看文档,英文原版那个<( ̄︶ ̄)>。
- 好吧,继续。首先配置好你准备角色的Avatar。至于怎么配置我这里说不清楚,去看看这方面的教程,最好是视频的。下图是我在Asset Store里下载的一个角色模型。我们就用它了
- 把角色拖入场景,不要有Rigibody,不要有Collider,Animator里不要有Controller。因为这些可能会影响角色的动画,但我们需要角色的各个节点都能自由移动
- 然后把AvatarController脚本拖给角色
- 新建一个空物体,命名为KinectManager,然后把KinectManager脚本拖给他
- 然后你可以运行测试一下了,这个机器人将会同步你的动作。没错,就是这么简单(>﹏<)。至于具体的参数什么的还是去看文档。这里不多说。
再入门
上面我们已经能让模型反映真实人的动作了,下面来讲解一下动作识别
- 首先,需要把KinectGestures脚本添加到KinectManager这个物体上。
- 新建一个空物体,命名为GestureListener。
- 新建一个脚本MyGestureListener.cs。这个脚本需要继承MonoBehaviour类并且实现KinectGestures.GestureListenerInterface接口。
- 具体函数的功能什么的在帮助文档里面有。先看关于手势识别的帮助文档,然后在来看下面的代码
代码:
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.");
}
} } - 这个代码我直接用的官方的实例修改的。为了显示出效果,可以新建一个空物体,添加上GUI Text组件,让他显示识别的效果
- 好了,你可以测试一下了
下面来讲关于手势识别的,上面讲的手势其实是Gesture的翻译,是全身的;下面讲的手势是针对于手的
好了,咋们。。。。︿( ̄︶ ̄)
继续入门
- 首先要知道Kinect可以识别的手势。定义在KinectInterop.HandState这个枚举类型中
- 你可以通过KinectManager的GetRightHandState(long UserID)来获取用户的右手手势状态(别问我怎么获取左手→_→)
- 下面发一段给电脑玩剪刀石头布的代码。代码比较粗糙,不过作为学习还是阔仪滴
<( ̄︶ ̄)>
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初级教程的更多相关文章
- Siki_Unity_1-6_C#编程初级教程(未学)
Unity 1-6 C#编程初级教程 任务1:C#和.Net框架 C#是.Net里的一个成分 2002年微软发布第一个.Net框架(多平台,行业标准,安全性) .Net框架 IDE编程工具 --产生- ...
- Python图像处理库:Pillow 初级教程
Python图像处理库:Pillow 初级教程 2014-09-14 翻译 http://pillow.readthedocs.org/en/latest/handbook/tutorial.html ...
- shellKali Linux Web 渗透测试— 初级教程(第三课)
shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...
- Mac OS X Terminal 101:终端使用初级教程
Mac OS X Terminal 101:终端使用初级教程 发表于 2012 年 7 月 29 日 由 Renfei Song | 文章目录 1 为什么要使用命令行/如何开启命令行? 2 初识Com ...
- Coding 初级教程(二)——上传已有项目
Coding 初级教程(二)——上传已有项目 [摘要:方针读者 :已具有 Coding.net 的账号. 本文首要先容若何把项目上传到 Coding.net 上. 分两种环境,一种是项目已归入到 gi ...
- [初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY
[初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY 发布者:sqqdugdu 时间:10-06 阅读数:2117 测试环境:RHEL 6.1,SecureCRT 5 ...
- Window服务初级教程以及log4net配置文件初始化
Window服务初级教程:http://www.jb51.net/article/48987.htm 另外,配置log4net这个日志功能的时候需要初始化,不然会报没有初始化的错误,而且初始化的节点应 ...
- 《自学C语言》初级教程 - 目录
我现在打算出一个C语言学习教程,目的是为了让初学者能够很容易和更深刻地理解C语言. 你可能有这样的疑问,网上不是有很多的初级教程吗,我需要这个吗?我的回答是:网上的C语言教程讲得不够全面,而且许多的初 ...
- Unity 4.3 2D 教程:新手上路
这篇文章译自 Christopher LaPollo 先生的 Unity 4.3 2D 教程的第一部分 Unity 4.3 2D Tutorial: Getting Started 感谢这套优秀教程的 ...
随机推荐
- JavaScript基本用法
首次创建 $(document).ready(function () { });
- c++ boost--------------boost::progress_timer小试。
//--------------------------------------------------------------------------- #include <vcl.h> ...
- PHP超时处理全面总结(转)
[ 概述 ] 在PHP开发中工作里非常多使用到超时处理到超时的场合,我说几个场景: 1. 异步获取数据如果某个后端数据源获取不成功则跳过,不影响整个页面展现 2. 为了保证Web服务器不会因为当个页面 ...
- WeChat 6.3 wipe deleted chat messages as well as LINE 5.3 and above
Let me show you the WeChat version first. It is 6.3. What will happen to WeChat deleted chat message ...
- Reactor模式解析——muduo网络库
最近一段时间阅读了muduo源码,读完的感受有一个感受就是有点乱.当然不是说代码乱,是我可能还没有完全消化和理解.为了更好的学习这个库,还是要来写一些东西促进一下. 我一边读一边尝试在一些地方改用c+ ...
- IOS中UIKit——UIButton的背景图像无法正常显示的原因
主要是在将图像引入项目中,没有选择Destination:Copy items if needed一项. 没有选择Destination:Copy items if needed一项,图像只能是以链接 ...
- Asp.net MVC4 Knockoutjs BootStrap Ace NinJect Jqgrid sqlserver2008
Asp.net MVC4 Knockoutjs BootStrap Ace NinJect Jqgrid sqlserver2008
- 不加班的实践(1)——这真的该用try-catch吗?
前言 我有个技能,就是把“我”说的听起来特别像“老子”. 以前是小喽啰的时候,会跟领导说“我!不加班.”,听起来就像“老子不加班!”一样.到最后发现,我确实没有把计划内的工作拖到需要加班才能完成,这个 ...
- nginx php 安装
.选定源码目录选定目录 /data/klj/ cd /data/klj/ 2.安装PCRE库cd /data/klj/wget ftp://ftp.csx.cam.ac.uk/pub/software ...
- CentOS7.0安装与配置Tomcat-7
解决权限不够 #chmod a+x filename 安装说明 安装环境:CentOS-7.0.1406安装方式:源码安装 软件:apache-tomcat-7.0.29.tar.gz 下载地址:ht ...