在unity中获取手的位置

创建一个空物体,命名为KinectManager,给该物体绑定上KinectManager 和 InteractionManager脚本

其中InteractionManager脚本上有三个纹理,Grip Hand Texture 是握拳,Release Hand Texture是手摊开的状态,Normal Hand Texture理论上应该是手呈半握状态并且其中的个别手指摊开,但是我从没有触发过

再新建一个空物体,命名为InteractionListener,新建一个脚本MyInteractionListener,这个脚本需要跟摄像机和InteractionManager相关联,但是InteractionManager可以用kinect的属性获取,所以只需要将摄像机拖拽到脚本上关联即可

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyInteractionListener : MonoBehaviour ,InteractionListenerInterface{

    [Tooltip("Camera used for screen ray-casting. This is usually the main camera.  用于屏幕光线投射的照相机。这通常是主相机。")]
    public Camera screenCamera;
    
    //[Tooltip("Interaction manager instance, used to detect hand interactions. If left empty, it will be the first interaction manager found in the scene.")]
    [Tooltip("交互管理器实例,用于检测手交互。如果为空,它将是场景中发现的第一个交互管理器")]
    public InteractionManager interactionManager;
    
    // hand interaction variables   手的交互变量
    private InteractionManager.HandEventType lastHandEvent = InteractionManager.HandEventType.None;

    // normalized and pixel position of the cursor  鼠标光标的统一化和位置
    private Vector3 screenNormalPos = Vector3.zero;
    private Vector3 screenPixelPos = Vector3.zero;
    private Vector3 newObjectPos = Vector3.zero;


    /*[Tooltip("Minimum Z-position of the dragged object, when moving forward and back.")]
    public float minZ = 0f;

    [Tooltip("Maximum Z-position of the dragged object, when moving forward and back.")]
    public float maxZ = 5f;*/


    /// <summary>
    /// UDP客户端
    /// </summary>
    public UDPClient udpClient;

    // Use this for initialization
    void Start () {
        //默认情况下,将主相机设置为屏幕摄像机
        if (screenCamera == null)
        {
            screenCamera = Camera.main;
        }
        // 获取交互管理器实例
        if (interactionManager == null)
        {
            interactionManager = InteractionManager.Instance;
        }
    }

    // Update is called once per frame
    void Update () {
        //如果交互管理器不为空,并且已经初始化
        if (interactionManager != null && interactionManager.IsInteractionInited())
        {

            // check if there is an underlying object to be selected    检查是否存在要选择的基础对象
            if (lastHandEvent == InteractionManager.HandEventType.Grip && screenNormalPos != Vector3.zero)
            {
                // convert the normalized screen pos to pixel pos   将标准化屏幕POS转换为像素POS
                screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();

                screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
                screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
                Ray ray = screenCamera ? screenCamera.ScreenPointToRay(screenPixelPos) : new Ray();

                // check if there is an underlying objects  检查是否存在底层对象
                RaycastHit hit;

                Debug.Log("握拳");
                Debug.Log(screenPixelPos);
                //udpClient.SocketSend(screenPixelPos.x + "," + screenPixelPos.y);
                //udpClient.SocketSend(screenNormalPos.x + "," + screenNormalPos.y);
                //udpClient.SocketSend(screenNormalPos.x.ToString("f2") + "," + screenNormalPos.y.ToString("f2"));//f2保留两位小数
                //udpClient.SocketSend("anXia");
                if (Physics.Raycast(ray, out hit))
                {
                    Debug.Log("位置");
                    Debug.Log(hit.point);
                    /*foreach (GameObject obj in draggableObjects)
                    {
                        if (hit.collider.gameObject == obj)
                        {
                            // an object was hit by the ray. select it and start drgging
                            draggedObject = obj;
                            draggedObjectOffset = hit.point - draggedObject.transform.position;
                            draggedObjectOffset.z = 0; // don't change z-pos

                            draggedNormalZ = (minZ + screenNormalPos.z * (maxZ - minZ)) -
                                draggedObject.transform.position.z; // start from the initial hand-z

                            // set selection material
                            draggedObjectMaterial = draggedObject.GetComponent<Renderer>().material;
                            draggedObject.GetComponent<Renderer>().material = selectedObjectMaterial;

                            // stop using gravity while dragging object
                            draggedObject.GetComponent<Rigidbody>().useGravity = false;
                            break;
                        }
                    }*/
                }
            }
            else
            {

                // continue dragging the object 继续拖动对象
                screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();

                // convert the normalized screen pos to 3D-world pos    将标准化的屏幕POS转换为3D世界POS
                screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
                screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
                /*//screenPixelPos.z = screenNormalPos.z + draggedObjectDepth;
                screenPixelPos.z = (minZ + screenNormalPos.z * (maxZ - minZ)) - draggedNormalZ -
                    (screenCamera ? screenCamera.transform.position.z : 0f);*/


                //Debug.Log("手掌");
                //Debug.Log(screenPixelPos);
                //udpClient.SocketSend(screenPixelPos.x + "," + screenPixelPos.y);
                //udpClient.SocketSend(screenNormalPos.x + "," + screenNormalPos.y);
                //udpClient.SocketSend(screenNormalPos.x.ToString("f2") + "," + screenNormalPos.y.ToString("f2"));
                //udpClient.SocketSend("taiQi");
                //newObjectPos = screenCamera.ScreenToWorldPoint(screenPixelPos) - draggedObjectOffset;

                // check if the object (hand grip) was released
                /*bool isReleased = lastHandEvent == InteractionManager.HandEventType.Release;

                if (isReleased)
                {
                    // restore the object's material and stop dragging the object
                    draggedObject.GetComponent<Renderer>().material = draggedObjectMaterial;

                    if (useGravity)
                    {
                        // add gravity to the object
                        draggedObject.GetComponent<Rigidbody>().useGravity = true;
                    }

                    draggedObject = null;
                }*/
            }
        }

    }
    public void HandGripDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
    {
        if (!isHandInteracting || !interactionManager)
            return;
        if (userId != interactionManager.GetUserID())
            return;

        lastHandEvent = InteractionManager.HandEventType.Grip;
        //isLeftHandDrag = !isRightHand;
        screenNormalPos = handScreenPos;
    }

    public void HandReleaseDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
    {
        if (!isHandInteracting || !interactionManager)
            return;
        if (userId != interactionManager.GetUserID())
            return;

        lastHandEvent = InteractionManager.HandEventType.Release;
        //isLeftHandDrag = !isRightHand;
        screenNormalPos = handScreenPos;
    }
    public bool HandClickDetected(long userId, int userIndex, bool isRightHand, Vector3 handScreenPos)
    {
        return true;
    }
}

 

需要注意的是,获取到的手的坐标是屏幕坐标,就是0---1的范围,如果想要应用,还需要转换成世界坐标,另外注意unity中的坐标轴,跟其他程序或软件的坐标轴可能会不同

posted on 2018-09-18 11:19  凌落成迷  阅读(4144)  评论(0编辑  收藏  举报