Unity3D快速接入LeapMotion

软件

Unity2018.3.5f1
Leap_Motion_Core_Assets_4.4.0.unitypackage

Tip

如果不想显示手模型,只往场景中拖入一个LeapHandController就够了。

效果图

在这里插入图片描述

LeapDebuger.cs

using System.Collections;
using System.Collections.Generic;
using Leap;
using Leap.Unity;
using UnityEngine;
using UnityEngine.UI;

public class LeapDebuger : MonoBehaviour
{
    public LeapProvider LeapDataProvider;
    public HandModelBase leftHandModel;
    public HandModelBase rightHandModel;

    public Text tipText;
    public RectTransform cursorImage;

    void Start()
    {
        if (LeapDataProvider == null)
        {
            LeapDataProvider = FindObjectOfType<LeapProvider>();
            if (LeapDataProvider == null || !LeapDataProvider.isActiveAndEnabled)
            {
                Debug.LogError("似乎没有找到LeapMotion连接");
                enabled = false;
                return;
            }
        }
    }

    Frame mFrame;
    string tip = "";
    string handName = "";
    Vector2 handPos;
    void Update()
    {
        mFrame = LeapDataProvider.CurrentFrame;
        tip = "\n手的数量: " + mFrame.Hands.Count;
        handPos = Vector2.zero;

        for (int i = 0; i < mFrame.Hands.Count; i++)
        {
            Hand hand = mFrame.Hands[i];
            handName = hand.IsLeft ? "左手" : "右手";

            Vector3 pos = hand.GetPalmPose().position;
            handPos = new Vector2(pos.x, pos.y);

            tip += "\n\n [" + handName + "] : " + hand.ToString() + " 掌宽: " + hand.PalmWidth.ToString("f3");
            tip += " 位置:(" + pos.x.ToString("f3") + "," + pos.y.ToString("f3") + "," + pos.z.ToString("f3") + ")";
            tip += "\n 四指抓握:" + IsHandGrab(hand);
            tip += " 握拳:" + IsHandFist(hand);
            tip += " 张开:" + IsHandOpenFull(hand);
            tip += " 静止:" + IsHandMotionless(hand);
            tip += "\n 两指捏合: " + IsHandPinch(hand);
            tip += " PinchDistance: " + (int)hand.PinchDistance;
            tip += " PinchStrength: " + hand.PinchStrength;
        }

        cursorImage.anchoredPosition = new Vector2(handPos.x.Map(-0.15f, 0.15f, 0, 1920), handPos.y.Map(0.1f, 0.3f, 0, 1080));

        //Debug.Log(Input.mousePosition + " , " + Camera.main.WorldToScreenPoint(cube.position));
        //Vector3 screenPos = Camera.main.WorldToScreenPoint(cube.position);
        Ray ray = Camera.main.ScreenPointToRay(new Vector3(cursorImage.anchoredPosition.x, cursorImage.anchoredPosition.y, 0));
        RaycastHit rayCastHit;
        if (Physics.Raycast(ray, out rayCastHit, 1000))
        {
            if (rayCastHit.collider.gameObject != null)
            {
                tip += "\n\n物体触发:" + rayCastHit.collider.gameObject.name;
            }
            //显示一条射线,只有在scene视图中才能看到
            Debug.DrawLine(ray.origin, rayCastHit.point, Color.red, 0.1f);
        }

        tipText.text = tip;
    }

    /// <summary>
    /// 左手是否检测到
    /// </summary>
    /// <returns></returns>
    public bool IsLeftHandTracked()
    {
        return leftHandModel.IsTracked;
    }

    /// <summary>
    /// 右手是否检测到
    /// </summary>
    /// <returns></returns>
    public bool IsRightHandTracked()
    {
        return rightHandModel.IsTracked;
    }

    /// <summary>
    /// 四指是否抓握
    /// </summary>
    public bool IsHandGrab(Hand hand)
    {
        // 抓手姿势中,手指和手之间的角度。这个角度是通过观察两个方向之间的角度来计算的
        // 4个手指和手的方向。不考虑拇指
        // 计算强度GrabStrength :   张开0 握紧1
        // 计算角度GrabAngle:       张开0弧度,当姿势开始达到拳头是π弧度
        return hand.GrabStrength > 0.8f;
    }

    /// <summary>
    /// 五指平伸 全部张开
    /// </summary>
    public bool IsHandOpenFull(Hand hand)
    {
        return hand.GrabStrength < 0.1f;
    }

    /// <summary>
    /// 大拇指和食指捏合
    /// </summary>
    /// <param name="hand"></param>
    /// <returns></returns>
    public bool IsHandPinch(Hand hand)
    {
        //捏手姿势中 拇指和食指之间的距离 0-110
        //Debug.Log((int)hand.PinchDistance);
        //张开0 捏合1
        //Debug.Log(hand.PinchStrength);
        return hand.IsPinching();
    }

    /// <summary>
    /// 握拳
    /// 握拳一定是捏合,捏合不一定是握拳
    /// </summary>
    public bool IsHandFist(Hand hand)
    {
        return hand.GetFistStrength() > 0.8f;
        //List<Finger> listOfFingers = hand.Fingers;
        //int count = 0;
        //for (int f = 0; f < listOfFingers.Count; f++)
        //{
        //    Finger finger = listOfFingers[f];
        //    if ((finger.TipPosition - hand.PalmPosition).Magnitude < 0.05f)
        //    {
        //        count++;
        //    }
        //}
        //return (count >= 4);
    }

    /// <summary>
    /// 静止不动
    /// </summary>
    public bool IsHandMotionless(Hand hand)
    {
        return hand.PalmVelocity.Magnitude < 0.02f;		//Vector3.Magnitude返回向量的长度
    }

    /// <summary>
    /// 这个方法用来扩展哪几个手指打开,这里传进来你要判断是否打开的手指 紧握手指 {} 传一个手指{Finger.FingerType.TYPE_RING}...
    /// 以此类推,当传进5个值得时候代表 手张开,当传进0个值的时候代表 握手
    /// </summary>
    /// <param name="hand"></param>
    /// <param name="arr"></param>
    /// <returns></returns>
    bool CheckFingerOpenToHand(Hand hand, Finger.FingerType[] fingerTypesArr, float deltaCloseFinger = 0.05f)
    {
        List<Finger> listOfFingers = hand.Fingers;
        float count = 0;
        // 遍历5个手指
        for (int f = 0; f < listOfFingers.Count; f++)
        {
            Finger finger = listOfFingers[f];
            // 判读每个手指的指尖位置和掌心位置的长度是不是小于某个值,以判断手指是否贴着掌心
            if ((finger.TipPosition - hand.PalmPosition).Magnitude < deltaCloseFinger)
            {
                // 如果传进来的数组长度是0,有一个手指那么 count + 1,continue 跳出,不执行下面数组长度不是0 的逻辑
                if (fingerTypesArr.Length == 0)
                {
                    count++;
                    continue;
                }
                // 传进来的数组长度不是 0,
                for (int i = 0; i < fingerTypesArr.Length; i++)
                {
                    // 假如本例子传进来的是食指和中指,逻辑走到这里,如果你的食指是紧握的,下面会判断这个手指是不是食指,返回 false
                    if (finger.Type == fingerTypesArr[i])
                    {
                        return false;
                    }
                    else
                    {
                        count++;
                    }
                }
            }
        }
        if (fingerTypesArr.Length == 0)
        {
            return count == 5;
        }
        // 这里除以length 是因为上面数组在每次 for 循环 count ++ 会执行 length 次
        return (count / fingerTypesArr.Length == 5 - fingerTypesArr.Length);
    }


    /// <summary>
    /// 判断四指是否靠向掌心
    /// </summary>
    /// <param name="hand"></param>
    /// <returns></returns>
    bool CheckFingerCloseToHand(Hand hand)
    {
        List<Finger> listOfFingers = hand.Fingers;
        int count = 0;
        for (int f = 0; f < listOfFingers.Count; f++)
        {
            Finger finger = listOfFingers[f];
            if ((finger.TipPosition - hand.PalmPosition).Magnitude < 0.05f)
            {
                if (finger.Type == Finger.FingerType.TYPE_THUMB)
                {
                    return false;
                }
                else
                {
                    count++;
                }
            }
        }
        return (count == 4);
    }
}

加入新媒体交互微信群,分享更多Unity开发技能

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值