美文网首页Unity 3D
Kinect结合Unity基础使用(二)

Kinect结合Unity基础使用(二)

作者: 冷暖自知_Super | 来源:发表于2020-04-07 10:54 被阅读0次

    一、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、人物抠图背景半透明

    clipboard.png

    2、坐标系

    • 屏幕坐标系:(左下角为原点)

    • 鼠标坐标系:(与屏幕坐标系一样,左下角是原点)

    • UGUI坐标系:(与鼠标坐标系类似,往右,x增大,往上,y增 大。原点与锚点有关)

    3、UI点击的实现:

      1. 获取右手(左手/关节)的3D坐标
      1. 3D坐标转换为屏幕坐标
      1. 屏幕坐标转换为UGUI坐标(得到手在UGUI的位置)
      1. 判断手的位置是否在UGUI控件上
      1. 手如果在UGUI控件上,判断是否握拳
      1. 握拳就表示点击了该UGUI
    clipboard2.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、人物进入场景监听

    clipboard3.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)
        {
            
        }
        
    }
    

    补充细节:脚本在上

    clipboard4.png

    相关文章

      网友评论

        本文标题:Kinect结合Unity基础使用(二)

        本文链接:https://www.haomeiwen.com/subject/kmuzphtx.html