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 感谢这套优秀教程的 ...
随机推荐
- ASP.NET的SEO:基础知识
本系列目录 首先谈一点我自己的体会,我还是希望能和大家分享: 当你读到一定数量的SEO资料后,你会发现,对同一个问题,众说纷纭,莫衷一是.这其实主要是因为以下一些原因造成的:1. 很多SEO技巧,是& ...
- 学习BFC
BFC全称是Block Formatting Context,即块格式化上下文.它是CSS2.1规范定义的,关于CSS渲染定位的一个概念.要明白BFC到底是什么,首先来看看什么是视觉格式化模型. 视觉 ...
- word文档中的字号和磅的对应关系
字号 磅 初号 42 小初 36 一号 26 小一 24 二号 22 小二 18 三号 16 小三 15 四号 14 小四 12 五号 10.5 小五 9 六号 7.5 小六 6.5 七号 5.5
- 软件工程 speedsnail 冲刺5
2015-5-9 完成任务:学习了黑马android教学视频10\11\12集,填写游戏人的姓名功能为明天的记分板准备: 遇到问题: 问题1 Suspicious method call; shoul ...
- Check Box Select/Deselect All on Grid
The below function is to be used on a grid with multiple check boxes. Place the code behind a FieldC ...
- T—SQL用法剪辑,方便以后查看
一.用T-SQL查询表中第n行到第m行数据的写法示例 假设这里的n=6,m=10则有以下两种写法,qusID可以不连续,如下: select top 5 * from tb_wenti where q ...
- SQL SERVER中查询参数为空(null)时默认查询所有的实现
最近在项目中碰到一个比较有意思的问题,网上查找了一些方法,在这里总结分享一下. 我们经常会碰到这样的场景:需要查询数据,有一些查询条件,但是查询的时候,我们希望在某个条件为空的时候,则不筛选这个条件, ...
- 理解 JavaScript Scoping & Hoisting(二)
理解 JavaScript Scoping & Hoisting(二) 转自:http://www.jb51.net/article/75090.htm 这篇文章主要介绍了理解 JavaScr ...
- php安装redis扩展连接redis服务器
扩展包的下载地址:https://github.com/nicolasff/phpredis/archive/2.2.4.tar.gz tar xf phpredis-2.2.4.tar.gz cd ...
- 分布式MySQL集群方案的探索与思考
转载:http://www.infoq.com/cn/articles/exploration-of-distributed-mysql-cluster-scheme?utm_campaign=rig ...