本次解析案例所需工具:XBOX2代,UnitykinectSDK版本:Kinect for unity sdk v2.9,unity版本:2017.4.35
1:新建unity工程,其他插件看项目需求需要再导入:2:新建场景,并创建空物体:GameManager,并在该物体上挂载图中对应的脚本:KinectManager是初始化体感设备接入数据的,必须要挂载。

3:获取体感设备得到的图像,在Update中实时检测(可能发生出界丢失图像的后果,所以需要实时监测)

    if ( KinectManager.Instance.IsInitialized()){//获取体感设备监测到的实时图像//  GetComponent<UnityEngine.UI.RawImage>().texture = KinectManager.Instance.GetUsersClrTex();//获取体感设备监测到的彩色图像 ,显示的非真是图像,表达能力有限,具体插上设备自己看!GetComponent<UnityEngine.UI.RawImage>().texture = KinectManager.Instance.GetUsersLblTex();}

4:手势识别检测代码:

 using System;
using System.Collections.Generic;using UnityEngine; public class HandTrailRender : MonoBehaviour
{private RectTransform canvasRectTransform;public bool isHandLeft ; float handTimer = 0.5f;private float maxHandTimer = 0.5f;#region 变量private TrailRenderer trailrenderer;Transform mSelfTrans; /// <summary>/// 线段的z轴坐标/// </summary>const float LINE_POS_Z = 10;Vector2 maxPos;#endregion//定义跟踪的骨骼private KinectInterop.JointType handRightType = KinectInterop.JointType.HandRight;private KinectInterop.JointType handLeftType = KinectInterop.JointType.HandLeft;//手部跟踪平滑度 private float distanceToCamera = 10f;void Awake(){ trailrenderer = transform.GetComponent<TrailRenderer>();mSelfTrans = transform;}void Update(){ //得到左右手的屏幕位置 Vector3 handrightPos = GetjointPos((int)handRightType);Vector3 handLeftPos = GetjointPos((int)handLeftType);transform.position = isHandLeft ? handLeftPos : handrightPos;}//获取手势的在屏幕上的坐标private Vector3 GetjointPos(int handType){if (KinectManager.Instance!=null&&KinectManager.Instance.IsInitialized()){if (KinectManager.Instance.IsUserDetected()){long userID= KinectManager.Instance.GetPrimaryUserID();if (GameManager.instance.kinectUserIDs!=null&&GameManager.instance.kinectUserIDs.Count>0){userID = GameManager.instance.kinectUserIDs[0];}else{userID = KinectManager.Instance.GetPrimaryUserID();}if (KinectManager.Instance.IsJointTracked(userID, handType)){//得到手势坐标Vector3 handPos = KinectManager.Instance.GetJointKinectPosition(userID, handType);if (handPos != Vector3.zero){// 3 d位置深度Vector2 posDepth = KinectManager.Instance.MapSpacePointToDepthCoords(handPos);ushort depthValue = KinectManager.Instance.GetDepthForPixel((int)posDepth.x, (int)posDepth.y);if (depthValue > 0){// 颜色pos深度posVector2 posColor = KinectManager.Instance.MapDepthPointToColorCoords(posDepth, depthValue);float xNorm = (float)posColor.x / KinectManager.Instance.GetColorImageWidth();float yNorm = 1.0f - (float)posColor.y / KinectManager.Instance.GetColorImageHeight();Vector3 vPosOverlay = Camera.main.ViewportToWorldPoint(new Vector3(xNorm, yNorm, distanceToCamera));return vPosOverlay; }} }}}return Vector3.zero;}
}

5:防止手势在不动的情况下被检测到碰到了物体可以在FixUpdate和Update中分别得到手势的坐标,当两个值在比较近的范围内视为没有动,值越大则在运动,可能有更好的方法判断是否在挥手,只是我没找到,反正我用自己的这个方法还行,至少达到我想要的效果;

 Vector3 updatehandPos;Vector3 fixupdatehandPos;private KinectInterop.JointType handRightType = KinectInterop.JointType.HandRight;void FixedUpdate(){fixupdatehandPos = GetVecDis();}void Update(){updatehandPos = GetVecDis();if (Vector3.Distance(updatehandPos, fixupdatehandPos) > 0.05f)print("手在动");elseprint("手未动");} private Vector3 GetVecDis(){if (KinectManager.Instance != null && KinectManager.Instance.IsInitialized()){if (KinectManager.Instance.IsUserDetected()){long userID = KinectManager.Instance.GetPrimaryUserID();if (GameManager.instance.kinectUserIDs != null && GameManager.instance.kinectUserIDs.Count > 0){userID = GameManager.instance.kinectUserIDs[0];}else{userID = KinectManager.Instance.GetPrimaryUserID();}if (KinectManager.Instance.IsJointTracked(userID, (int)handRightType)){//得到手势坐标var handPos = KinectManager.Instance.GetJointKinectPosition(userID, (int)handRightType);return handPos;}}}return Vector3.zero;}

6:KinectSDK核心的代码都在KinectManager中,可以具体详看,这里不做解析,再看下实例话的代码如下,比较粗糙,能达到效果就行。。。。

using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.Diagnostics;public class GameManager : MonoBehaviour
{ public GameObject handImage; /// <summary>/// 获得的积分/// </summary>[HideInInspector]public float mGetScore { get; set; }/// <summary>/// 毒品元素实例化对象的父级/// </summary>public GameObject SpawnManager; //画板边界定义private int maxX = 800;private int minX = -800;private int minY = -650;//定义水果上抛的力private int forceX = 8;private int forceY = 15;int fruitCount ;/// <summary>/// [Header("炸弹的预设")]/// </summary>[Header("炸弹的预设")]public GameObject bomb; /// <summary>/// 产生时间/// </summary>float spawnerTimer = ItemConfig.PRODUCEITEM_TIME;bool isPlaying = true;#region 单例以及游戏资源加载变量/// <summary>/// 单例对象/// </summary> public static GameManager instance = null;/// <summary>/// 读取游戏状态/// </summary>[HideInInspector]public E_GameState mGameState;[HideInInspector]public List<DataModen> datasModen = null;[HideInInspector]public bool isHandMoveCut = false;[HideInInspector]public GameObject panelStar = null;#endregionprivate void Awake(){instance = this;}// Start is called before the first frame updatevoid Start(){fruitCount = Random.Range(1, 2);Screen.SetResolution(1920,1080,true);MusicMgr.Instance.PlayBkMusic("待机");InitResetGame(true);if (panelStar==null)panelStar = Instantiate(Resources.Load<GameObject>("Prefabs/PanelStart"), SpawnManager.transform);if (!System.IO.Directory.Exists(ItemConfig.LoadPath))System.IO.Directory.CreateDirectory(ItemConfig.LoadPath);mGameState = E_GameState.ready; datasModen = UtilsJson<DataModen>.UseNetFrameReadJsonConfigFiles(ItemConfig.LoadPath, "ItemData.json");if (datasModen == null || datasModen.Count <= 0)print("MJ   =======>  对象为空或者对象数量为0");var timer = UtilsJson<GameDataTimer>.ReadJsonConfigFile(ItemConfig.LoadPath, "GameTimer.json");
#if UNITY_EDITORItemConfig.MAX_GAMETIME = 10;
#elif UNITY_STANDALONE_WINItemConfig.MAX_GAMETIME = timer.mTimer;
#endifItemConfig.COUNTDOWNTIME = timer.mCountdown;Invoke("SetFruitCout",5f);}public void InitResetGame(bool isActive) { handImage.SetActive(isActive); mGameState = isActive ? E_GameState.ready : E_GameState.inGame; }public void SetFruitCout(){fruitCount = Random.Range(1,5);}/// <summary>/// 产生水果 炸弹 ,也能控制销毁/// </summary>private void OnSpwaner(bool isFruit){//播放音乐// audioSource.Play(); //实例化水果int fruitIndex = Random.Range(0, datasModen.Count);GameObject go;int fruitX = Random.Range(minX, maxX);go = Instantiate(bomb, new Vector3(fruitX, minY, 0), bomb.transform.rotation);go.transform.SetParent(SpawnManager.transform);//14是炸弹   int fIndex = isFruit ? Random.Range(0, 14) :14;go.GetComponent<FruitItem>().SetType(fIndex);RectTransform fruitRT = go.transform as RectTransform;fruitRT.anchoredPosition3D = new Vector3(0, 0, 0);fruitRT.anchoredPosition = new Vector2(fruitX, minY);fruitRT.localScale = new Vector3(1, 1, 1);//水果速度// Vector3 velocity = new Vector3(-x * Random.Range(0.2f, 0.5f), -Physics.gravity.y * Random.Range(0.8f, 1.5f), 0);Rigidbody2D rigidbody = go.transform.GetComponent<Rigidbody2D>();float xxx = fruitX > 0 ? -Random.Range(1, forceX) : Random.Range(1, forceX);rigidbody.velocity = new Vector2(xxx, Random.Range(forceY -3, forceY));}public List<long> kinectUserIDs;// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.Escape)){Application.Quit();}try{if (mGetScore <= 0){mGetScore = 0;}if (KinectManager.Instance.IsInitialized()){kinectUserIDs = KinectManager.Instance.GetAllUserIds();for (int i = 0; i < kinectUserIDs.Count; i++){print("当前用户列表=;;;;;" + kinectUserIDs[i]);}}if (mGameState == E_GameState.inGame){if (!isPlaying){return;}spawnerTimer -= Time.deltaTime;if (0 >= spawnerTimer){//到时间就开始产生水果,产生多个水果for (int i = 0; i < fruitCount; i++)OnSpwaner(true);spawnerTimer = ItemConfig.PRODUCEITEM_TIME;//随机产生炸弹int bombNum = Random.Range(0, 100);if (bombNum > 70){OnSpwaner(false);}}}}catch (System.Exception){}}
}

7:sdk中手势识别有个枚举类型,定义了相当多的手势:

public enum Gestures
{None = 0,RaiseRightHand,//右手举起过肩并保持至少一秒RaiseLeftHand,//左手举起过肩并保持至少一秒Psi,//双手举起过肩并保持至少一秒Tpose,//触摸Stop,//双手下垂Wave,//左手或右手举起来回摆动Click,//左手或右手在适当的位置停留至少2.5秒SwipeLeft,//右手向左挥SwipeRight,//左手向右挥SwipeUp,//左手或者右手向上挥SwipeDown,//左手或者右手向下挥RightHandCursor,//假手势,用来使光标随着手移动LeftHandCursor,//假手势,用来使光标随着手移动ZoomIn,//手肘向下,两手掌相聚至少0.7米,然后慢慢合在一起ZoomOut,//手肘向下,左右手掌合在一起(求佛的手势),然后慢慢分开Wheel,//想象一下你双手握着方向盘,然后左右转动Jump,//在1.5秒内髋关节中心至少上升10厘米 (跳)Squat,//在1.5秒内髋关节中心至少下降10厘米 (下蹲)Push,//在1.5秒内将左手或右手向外推Pull,//在1.5秒内将左手或右手向里拉ShoulderLeftFront,//左肩前倾ShoulderRightFront,//右肩前倾LeanLeft, //身体向左倾斜LeanRight, //身体向右倾斜LeanForward,//身体向前倾斜LeanBack,//身体向后倾斜KickLeft,//踢左脚KickRight,//踢右脚Run,//跑RaisedRightHorizontalLeftHand,//左手平举RaisedLeftHorizontalRightHand,//右手平举//自定义手势UserGesture1 = 101,UserGesture2 = 102,UserGesture3 = 103,UserGesture4 = 104,UserGesture5 = 105,UserGesture6 = 106,UserGesture7 = 107,UserGesture8 = 108,UserGesture9 = 109,UserGesture10 = 110,
}

8:打包注意事项,工程中测试没问题,打包出来不行,可能原因有很多,首先检查下打包后的目录与运行程序同级的目录中是否导入了Kinect相关的Dll文件,这些需要手动导入:文件在工程目录下,Assets的同级目录中可以找到。

9:体感设备的KinectSDK(非Unity)出现如下错误的解决方案:查看服务项是否开启,或查看电源以及线路是否正常;多次查到该问题的原因基本都是这两个问题。

最后该作品已经部署到湖南岳阳禁毒博物馆中,体感切水果互动项目,有想法的可以去体验体验,觉得有用的点个赞再走,有宝贵意见的欢迎大家留言提示,这里会针对性的进行更改并更新,感谢!!!

Kinect体感SDK接入以及切水果案例代码分析相关推荐

  1. 制作Kinect体感控制小车教程 <一>

    转载请注明出处:http://blog.csdn.net/lxk7280                                        Kinect体感控制小车        Kine ...

  2. 制作Kinect体感控制小车教程 lt;一gt;

    转载请注明出处:http://blog.csdn.net/lxk7280                                        Kinect体感控制小车        Kine ...

  3. Kinect体感机器人(二)—— 体感识别

    Kinect体感机器人(二)-- 体感识别 By 马冬亮(凝霜  Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 背景知识 体感技术属于NUI(自然人机界面)的 ...

  4. Kinect体感机器人(三)—— 空间向量法计算关节角度

    Kinect体感机器人(三)-- 空间向量法计算关节角度 By 马冬亮(凝霜  Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 终于写到体感机器人的核心代码了, ...

  5. 基于Kinect体感器控制的机械臂项目记录

    基于Kinect体感器控制的机械臂 项目介绍 上位机代码说明 1.识别部分 1.1GetPosition.cpp 1.2 KinetJiointFilter.cpp 1.3 1.4 SerialPor ...

  6. 用多个Kinect体感摄像头实现真正360度运动捕捉系统

    以前我在这里写过博客文章,研究用微软的Kinect体感摄像头做运动捕捉,当时设计了两种方案,一种是用NiTE中间件,在它的基础上改进了一点点,但处理360度转身主要靠插值,说白了就是靠猜测,效果不是很 ...

  7. 基于Kinect体感的仿真对抗游戏系统

    项目意义: 1.Kinect的研究和应用在国内外都呈现出比较高的热潮,相关技术,如人脸识别.动态跟踪.手势识别等均出现了比较优越的实际效果.让机器人能够实时跟踪人的动作功能并完成与人的沟通互动是机器人 ...

  8. Kinect体感互动解决方案——体感炫舞互动系统

    儿童乐园.商场人流较少.缺乏活力.死气沉沉? 可能你需要的是Kinect体感炫舞互动游戏. 佩京体感炫舞互动游戏,为儿童乐园.商场注入更多互动活力,您带来从未有过的超级酷炫体验,其精彩纷呈的动态舞台场 ...

  9. (转)Kinect体感机器人—— 空间向量法计算关节角度

    Kinect体感机器人(三)-- 空间向量法计算关节角度 By 马冬亮(凝霜  Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 终于写到体感机器人的核心代码了, ...

最新文章

  1. Unity3D 镜面反射
  2. 校园音乐点歌平台的设计与开发 微信小程序 点歌系统 java 开发
  3. php多个域名301重定向到主域名代码,Nginx 301和apache重定向域名规则方法(多个域名,单个域名)...
  4. mysql hive 内置函数_Hive中与时间相关的内置函数
  5. 计算机绘图实训,计算机绘图实训-杜兰萍主编.pdf
  6. charles 抓包 (二)
  7. Sprinig Boot + Redis 实现接口幂等性,写得太好了!
  8. NRF24L01模块配置
  9. 巨型帧linux检测,linux – KVM来宾和主机之间的巨型帧?
  10. 测试SQLServer拆分字符串到临时表
  11. php的数组操作,PHP的数组操作
  12. VSCode中使用vue项目ESlint验证配置
  13. jfinal使用配置文件注意事情
  14. 阿里巴巴字体库的下载以及三种用法
  15. 微软商店点下载没反应
  16. mysql从入门到精通pdf百度云明日科技_PHP从入门到精通(第3版) 明日科技 中文完整pdf扫描版[42MB]_IT教程网...
  17. 静态路由绑定探测组功能的配置
  18. iOS中都有什么设计模式?各个设计模式的作用?
  19. apache实验报告 linux_Apache服务器配置实验报告
  20. c语言mfc怎么插入背景图片,MFC 对话框添加背景图片详细过程(两种方法)

热门文章

  1. c语言低通滤波程序,一阶低通滤波器c语言
  2. 做一款属于自己的“签名设计软件”,外行玩儿过都说牛逼
  3. CTF.show:萌新专属红包题
  4. ssm+java计算机毕业设计保险公司外勤人员信息管理baov3(程序+lw+源码+远程部署)
  5. Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树
  6. 电子价签与动态价格调整算法与策略
  7. android 磁盘检测工具下载,Cross Platform Disk Test app
  8. 用 Rails 搭建微信公众平台 API
  9. Fine-grained Fact Verification with Kernel GA Network
  10. 城市轨道交通运营票务管理论文_城市轨道交通票务管理(城市轨道交通运营管理第2版智媒体版城市轨道交通职业教育系列教材)...