Kinect结合Unity基础使用(二)
2020-04-07 本文已影响0人
冷暖自知_Super
一、Kinect for Unity插件
插件:Kinect v2.9.unitypackage
官方案例:
-
Kinect for Unity官方示例演示:
-
OverlayDemo:小球跟收手走
-
GesturesDemo:手滑动,翻转立方体
-
InteractionDemo: 握拳移动物体
-
AvatarsDemo:场景中的人物跟着玩家运动
二、Kinect Manager使用
第一步:camera上挂载Kinect Manager脚本
1、显示彩色数据流
KinectManager.Instance.GetUsersClrTex();获取用户彩色贴图
勾选compute color map
public RawImage kinectImg;
void Update()
{
bool isInit = KinectManager.Instance.IsInitialized();
if (isInit)
{
//Kinect准备好了
if (kinectImg!=null && kinectImg.texture==null)
{
//彩色数据流
Texture2D kinectPic = KinectManager.Instance.GetUsersClrTex();//获取用户彩色贴图
kinectImg.texture = kinectPic; //把彩色数据给控件显示
}
}
}
2、显示深度数据流
KinectManager.Instance.GetUsersLblTex();//获取深度数据
勾选 Kinect Manager脚本组件的 compute use map
(同时勾选compute color map、compute use map)类似PS抠图
public RawImage kinectImg;
void Update()
{
bool isInit = KinectManager.Instance.IsInitialized();
if (isInit)
{
//Kinect准备好了
if (kinectImg!=null && kinectImg.texture==null)
{
//深度数据流
Texture2D kinectUseMap = KinectManager.Instance.GetUsersLblTex();//获取深度数据
kinectImg.texture = kinectUseMap;
}
}
}
三、Kinect Manager使用2
1、获取人物ID
long userId = KinectManager.Instance.GetPrimaryUserID();
2、获取关节信息
获取左手位置
GetJointKinectPosition() 获取的是相对于Kinect的坐标
GetJointPosition() 获取的是经过转换得到的坐标(Y值加上Kinect设备高度)
if (KinectManager.Instance.IsUserDetected()){
//检测到玩家
long userId = KinectManager.Instance.GetPrimaryUserID();
int jointType = (int)KinectInterop.JointType.HandLeft;
if (KinectManager.Instance.IsJointTracked(userId, jointType))
{
//关节点被追踪到
//GetJointKinectPosition坐标
Vector3 leftHandKinectPos = KinectManager.Instance.GetJointKinectPosition(userId, jointType);
print("kx = " + leftHandKinectPos.x + " ky = " + leftHandKinectPos.y + " kz = " + leftHandKinectPos.z);
//GetJointPosition坐标
Vector3 leftHandPos =KinectManager.Instance.GetJointPosition(userId, jointType);
print("x = " + leftHandPos.x + " y = " + leftHandPos.y + " z = " + leftHandPos.z);
}
}
3、获取手势状态
KinectManager.Instance.GetLeftHandState(userId);获取左手手势状态
if (KinectManager.Instance.IsUserDetected()){
//检测到玩家
long userId = KinectManager.Instance.GetPrimaryUserID();
int jointType = (int)KinectInterop.JointType.HandLeft;
if (KinectManager.Instance.IsJointTracked(userId, jointType))
{
//关节点被追踪到
KinectInterop.HandState leftHandState = KinectManager.Instance.GetLeftHandState(userId);
if(leftHandState == KinectInterop.HandState.Closed)
{
print("左手握拳");
}else if (leftHandState == KinectInterop.HandState.Open)
{
print("左手打开");
}else if (leftHandState == KinectInterop.HandState.Lasso)
{
print("Yes 手势");
}
}
}
4、获取用户信息
if (KinectManager.Instance.IsUserDetected()){
//检测到玩家
long userId = KinectManager.Instance.GetPrimaryUserID();
//获取用户离体感多远
Vector3 userPos = KinectManager.Instance.GetUserPosition(userId);
print("userPos x ="+userPos.x+ " userPos y =" + userPos.y+ " userPos z =" + userPos.z);
}
四、练习
1、人物抠图背景半透明
![](https://img.haomeiwen.com/i22758595/fa4b5197130b33b1.png)
2、坐标系
-
屏幕坐标系:(左下角为原点)
-
鼠标坐标系:(与屏幕坐标系一样,左下角是原点)
-
UGUI坐标系:(与鼠标坐标系类似,往右,x增大,往上,y增 大。原点与锚点有关)
3、UI点击的实现:
- 获取右手(左手/关节)的3D坐标
- 3D坐标转换为屏幕坐标
- 屏幕坐标转换为UGUI坐标(得到手在UGUI的位置)
- 判断手的位置是否在UGUI控件上
- 手如果在UGUI控件上,判断是否握拳
- 握拳就表示点击了该UGUI
![](https://img.haomeiwen.com/i22758595/b703bdf4b6b4ff2d.png)
代码实现:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UGUI_Test : MonoBehaviour
{
public Canvas canvas;
public Image rightHand;
public Image btn1;
void Update()
{
if (KinectManager.Instance.IsUserDetected())
{
long userId = KinectManager.Instance.GetPrimaryUserID();//获取用户ID
int jointType = (int)KinectInterop.JointType.HandRight;//表示要追踪的是右手
if (KinectManager.Instance.IsJointTracked(userId, jointType))
{
Vector3 rightHandPos = KinectManager.Instance.GetJointKinectPosition(userId, jointType);//步骤1
Vector3 rightHandScreenPos = Camera.main.WorldToScreenPoint(rightHandPos);//右手位置转化到屏幕坐标 步骤2
Vector2 rightHandSenPos = new Vector2(rightHandScreenPos.x,rightHandScreenPos.y);
Vector2 rightHandUGuiPos;
if(RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform,
rightHandSenPos,null, out rightHandUGuiPos))
{
//表示右手在canvas所表示的矩形范围
RectTransform rightRectTf = rightHand.transform as RectTransform;
rightRectTf.anchoredPosition = rightHandUGuiPos;
}
if (RectTransformUtility.RectangleContainsScreenPoint(btn1.rectTransform,
rightHandScreenPos, null))
{
//检测到点在rect里面的时候才会返回true
print("手在按钮一上悬停");
KinectInterop.HandState rightHandState = KinectManager.Instance.GetRightHandState(userId);
if(rightHandState == KinectInterop.HandState.Closed)
{
print("右手握拳");
}
}
else
{
print("手从按钮一离开");
}
}
}
}
}
五、RectTransformUtility静态方法:
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform rect ,Vector2 screenPoint,Camera cam,out Vector3 worldPoint);
转换屏幕空间,指向RectTransform位于矩形平面的局部空间中的位置。
根据屏幕坐标与相对矩形rect摄像机和cam而言来计算本地坐标。
RectTransformUtility.ScreenPointToWorldPointInRectangle(RectTransform rect ,Vector2 screenPoint,Camera cam,out Vector3 worldPoint)
转换屏幕空间,指向世界空间中给定的RectTransform平面上的位置。
根据屏幕坐标与相对矩形rect和摄像机cam而言来计算出世界坐标。
4、UGUI动画效果:
Animator
Animation
DoTween插件
六、姿势的检测与监听
1、人物进入场景监听
![](https://img.haomeiwen.com/i22758595/576406da48c3212d.png)
2、使用接口进行人物姿势监听
接口:KinectGestures.GestureListenerInterface
public class GestureTest : MonoBehaviour,KinectGestures.GestureListenerInterface
{
private Text text;
void Start()
{
text = GetComponent<Text>();
}
void Update()
{
}
public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint)
{
return true;
}
public void UserDetected(long userId, int userIndex)
{
if(text != null)
{
text.text += " 检测到用户了 ";
}
}
public void UserLost(long userId, int userIndex)
{
if (text != null)
{
text.text += " 用户离开摄像头 ";
}
}
public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint, Vector3 screenPos)
{
if (gesture == KinectGestures.Gestures.SwipeRight)
{
text.text += " 用户做了SwipeRight手势 ";
}
else if (gesture == KinectGestures.Gestures.SwipeLeft)
{
text.text += " 用户做了SwipeLeft手势 ";
}
return true;
}
public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture, float progress, KinectInterop.JointType joint, Vector3 screenPos)
{
}
}
补充细节:脚本在上
![](https://img.haomeiwen.com/i22758595/e5cef28c7e00e8a1.png)