以下所有的代码操作的要求均建立在官方的KinectSDK1.5的基础上(除DEMO版,1.0的也通用,至于有些用OPEN NI的,我的方法应该有些辅助作用)
一.全屏:
思路:
Kinect的手的节点(这里都是右手,左手的效果一致)在Unity中移动的距离是很小的,你可以用一个物体绑定到手上,然后就能看到具体能够移动多大的范围了。
正式开始:1.因为手的移动范围很小,因此建立一个虚拟的小屏(2D,屏幕坐标),长宽就是你手上下左右移动的最大距离(在Unity中)。
2.换算出虚拟小屏的X/Y轴与实际屏幕的X/Y轴的比例,可以保存可以不保存,这个自己记住就成大小无所谓,甚至可以考虑相应的稍微减少一点值,以方便比你更加瘦小的人使用到全屏功能。但请记住,这个虚拟小屏是固定的不会移动的,要移动的是实际操作的人。
3.将手的世界坐标利用Camera.WorldToScreenPoint(手的Position位置)换算出屏幕坐标点,并保存好Z轴的值。
4.算出手的屏幕坐标与虚拟小屏X/Y轴的比例,然后利用第2步中得到的虚拟屏幕与实际屏幕的比例,可以得到一个虚拟的扩大后的手的屏幕坐标。(具体算法请自己考虑。)
5.利用第5步算出的X/Y轴的值,加上第3步得到的Z轴的值,通过Camera.ScreenToWorldPoint()方法得到在Unity中的世界坐标的Position值(这个值是虚拟出来的)
6.将第5步取得的Position值实时的赋给某个作为鼠标的物体的transform.position.
利用以上6步就能做到鼠标物体全屏移动了。
二。防抖:
因为通过Kinect取得的手的坐标点是在不断的抖动的,因此,如果你仅仅是利用“一”中的思路去做,可能看到的效果是手在不停的抖动的。因此我们需要防抖。
思路:1不断的去算鼠标物体(以后用鼠标代替)与“一”中得到的虚拟实际坐标的距离
2.利用Mathf.Lerp来不断的改变鼠标的Position的值。
3.提示,可以自己设定一个数值变换的速度,然后考虑将距离融入到速度中去。。。
其实上就是将“全屏”的第6步换成上面的1+2两步。。
三。模拟鼠标点击:
要利用Kinect去模拟鼠标点击的功能,必须要使用一个物体作为屏幕中的鼠标代替实际的物理鼠标。然后利用上面的:全屏+防抖方法使Kinect能够控制鼠标物体满屏移动。
因为是利用物体模拟的鼠标,所以了,OnMouseDown肯定是没用的啦。所以要利用到了OnTriggerEnter()和OnTriggerExit()方法了。
为了确保鼠标能够点击到按钮,那么就需要将按钮的Collider范围扩大,并且最好能够保持鼠标和按钮处在同一平面或者相互平行的平面,且鼠标与摄像机的相对距离要比按钮与摄像机的相对距离小(若要如此设定,那么在"全屏”中的第6步中,改变的将仅仅是X/Y的值,Z的值用鼠标的原始值;同理,在“防抖”中第2步改变的值也只是X/Y轴的值,Z轴用原始的鼠标物体的值。)。
重点建议:如果要保证鼠标始终在屏幕内,那么最好是用一个正交摄像机去单独渲染鼠标物体和所有的按钮。那么以上的所有的计算用到的摄像机类(Camera)都是这次设定的正交摄像机了。
1.若要Unity+Kinect结合进行开发,建议访问 http://wiki.etc.cmu.edu/unity3d/index.php/Microsoft_Kinect_-_Microsoft_SDK 以及http://channel9.msdn.com/coding4fun/kinect/KinectSDK--Unity3D-Interface-v5-now-Kinect-for-Windows-SDK-v1-compatible 这两个网址都是介绍如何使用Windos的SDK与Unity结合进行开发的教程。当然,都是英文版,第一个会比较详细一点。第二个只是简单的进行了介绍。但是两个都有具体的Unity项目进行下载。
2.开发Unity与Kinect结合的项目,不需要购买Kinect Sensor for Windows(坛子里有人问到了这个问题) 千万不要被奸商给坑了。根本不需要的,至于为什么,看1里面提到的两个网站的教程就知道了。
附加一个问题:我现在开发的项目在编辑器里面能够正常执行,但是导出成EXE之后却不能用了,不知道是为什么?我使用的是微软官方的最新SDK版本。如有童鞋知道,请告知,万分感谢。
=====================================================================
最近公司主攻Unity+Kinect开发,需要用到很多的Kinect的动作并绑定到Unity中进行操作。
在开发过程中遇到以下几件小事,可能大家以后开发的时候也需要注意的。
1.人物骨骼绑定之后的,在Unity界面中默认手是不可能完全划到整块屏幕的。所以需要在Unity中添加一定的算法确保双手能够划到整块屏幕。
2.由于是通过Kinect进行操作,那么OnMouse****之类的方法肯定是用不了的啦。我利用的是发射线,但是这很明显是个愚蠢的做法。而且很多时候射线出发会出现很多的问题。
3.不同版本的Kinect SDK包是不能通用的(针对微软官方的SDK),并且非常坑爹是高版本也不兼容低版本?不知道是我同事的脚本写法有问题还是怎样。我个人还未研究Kinect的开发。
4.Kinect的坐标系统和Unity的坐标系统都是笛卡尔坐标系,但有一点区别是Kinect与Unity的Z轴是反向的。X/Y轴一致。
5.若需要将手与摄像头进行位置/角度绑定,那么必须要添加一个脚本,确保手的在某个范围内时返回一个固定值。若非如此,你会发现摄像头会像抽风了一样的抖动,原因是Kinect检测到的人物手的坐标是不停变换的,即使你感觉你的手没有动。