LEAPMotion猎户座(VR)开发~002~


LEAPMotion猎户座(VR)开发教程~002~

Created by miccall (转载请注明出处)
  • 上一讲讲的比较杂,也比较难 本篇将从基本讲起 ,一步步带你登天装逼

    看见你的手

  • 打开unity 3d 创建一个工程 导入4.1.4的包 (好像又更新了??算了,不管他)
  • LeapMotion目录下 找到Scenes 里有三个场景 分别是AR DESKTOP 和 VR 三个模式
  • 我们打开一个 运行一下 看看效果

game视图

  • 上一篇也跟大家提了一下脚本 。 我们这次细看一下工程结构
  • 在Hierachy界面 我们看到的是一个官方给的样例
  • camera下面一个LeapHandController 物体 他挂着我们上一篇提到的三个脚本 就其他的你不去细研究也没关系 。我们主要还是看看第三个脚本 Hand Pool 之之前我也没去细看 最近在工程里面,老大让我去换手的模型,我不得不看了看找个脚本
  • 其实也蛮简单的 。 Model Pool 模型池 先设置了他的size。表示模型手有几对。在工程目录的camera下面的一个HandModels 的子物体中 ,放了 Hand的capsule(mesh模型)以及Rigid(大概可以理解为碰撞器吧)

这里写图片描述

  • 后缀不说了吧 R为右 L为左 其他的大概都是一些基本的英文单词 程序员应该顾名思义了,但是考虑到大多数人,我就简单提一下 。
Rigid ch bone
thumb 大拇指 -3个骨节
index 食 指 3个骨节
middle 中指 3个骨节
ring 无名指 3个骨节
pinky 小拇指 3个骨节
palm 手掌 #
forearm 前 臂 #
  • 基本的工程结构就是这样了 。在Hand Pool 下面 依次把他们拖进去
    这里写图片描述
  • 注意托的时候 左右要分清楚 左右对也要分清楚 。

  • 换模型的教程我以后会贴出来 今天就讲这么多了

程序员的疑惑

怎获取手的数据 供我么开发使用呢 ???
当然我上一篇文章提到了LeapProvider,就是它了 。
接下来呢 ,带大家做一个小东西 先来感受一下unity 结合leap的乐趣。

  • 首先 先建一个plane到场景中 修改他的scale 把它放大一点,再把它往下面托一点让leap稍微的在plane的上面。

  • 第二步 建立一个cube的预制体 ,当然 sphere 会更好玩 。

  • 调整位置 让场景全部可视 这个就不用我多教了吧 unity的基本功 。

  • 第三步 创建不同的材质颜色 分别给plane和cube不同的颜色区分

  • 好 完成这个部分 我们就来先在game当中预览一下效果 还不错的话 就跟着我做下一步啦 不满足的自己调整调整

这里写图片描述

  • 好,来 ,我们给cube 添加一个刚体(RigedBody) 再次运行看看 。没错,跟我们预想的一样,它收重力影响,掉落到plane上面 。

  • 然后呢,哈哈 ,当然是把手伸出来了 去碰一碰哪个cube 。他会在你手的触碰下,呈现跟现实差不多的效果 。

  • 玩过了实体操作 ,我们接下来做一些基本的代码演示 。

  • 鉴于下一章直接要讲一些功能的实现方式 我们在此直接贴出一些代码供大家调试
    using Leap;
    using Leap.Unity;
    注意了 ,加入必要的命名空间

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

public class debug : MonoBehaviour {

  Frame frame; //  当前帧对象
  Frame lastframe;  // 前一帧
  Hand righthand;   //当前的右手对象
  Hand lefthand;     // 当前的左手对象
  Hand lastrighthand;   //上一帧的右手对象
  Hand lastlefthand;    // 上一帧的左手对象
  List<Hand> handlist;     //当前的手的集合

    // Use this for initialization
    void Start () {
        provider = FindObjectOfType<LeapProvider>() as LeapProvider;  //获取手的提供者对象
    }

    // Update is called once per frame
    void Update () {
      inithand();  //初始化手的信息
      //Hnaddebug(righthand);  //调试用的
      //Framedebug(frame);
    }
    private void inithand()
    {
        frame = provider.CurrentFrame;
        handlist = frame.Hands;
        //print("handcont" + handlist.Count);
        if (handlist.Count > 0)
        {
            foreach(Hand h in handlist)  //遍历手的集合 数组
            {
                if (h.IsLeft) //判断左手还右手
                {
                    lefthand = h;
                    lastlefthand = frame.Hand(lefthand.Id);  //根据hand的id 来获取上一帧的手的信息  
                    //print("isleft");
                }
                if (h.IsRight)   //同理 右手也一样
                {
                    righthand = h;
                    lastrighthand = frame.Hand(righthand.Id);
                    //print("isright");
                }
            }
          }

      }
      //这些信息都是基于leap的坐标系 ,如果要转化成unity的坐标系 就要调用leap给的一个Utils 类 UnityVectorExtension
    void Hnaddebug(Hand h)
    {
        print("PalmPosition手掌的位置 "+h.PalmPosition
            +"手的id"+h.Id
            +"手掌的垂直向量"+h.PalmNormal
            +"手掌向手指方向的向量"+h.Direction
            +"手掌移动速度(矢量)"+h.PalmVelocity
            +"手指的捏合力"+h.PinchStrength
            +"手指的握和力"+h.GrabStrength
            );
    }
    void Framedebug(Frame f)
    {
        print("frame id "+f.Id
             +"frame每一帧检测到手的列表"+f.Hands
            );
    }
    //UnityVectorExtension 类的基本用法 。
    void leap_unity(){
      Vector3 palmnomal = UnityVectorExtension.ToVector3(righthand.PalmNormal);
      Vector3 palmposition = UnityVectorExtension.ToVector3(righthand.PalmPosition);
      Vector3 palmDirection = UnityVectorExtension.ToVector3(righthand.Direction);
      //Debug输出一下 ,就能看到场景下各个向量的线了 很直观 。
      Debug.DrawLine(palmposition, palmnomal, Color.red);
      Debug.DrawLine(palmposition, palmDirection, Color.green);
      Debug.DrawLine(palmposition, Vector3.Cross(palmnomal, palmDirection), Color.blue);
    }
}
  • 还是简单解释一下这些调试 。
  • Hand.id <====> LEAP分配给此Hand对象的唯一ID,他的值在连续frame中保持相同。如果leap检测不到手(例如,当手被另一只手遮挡时,或者当手从Leap Motion Controller视野中消失或到达Leap Motion Controller视野的边缘时),Leap Motion软件可以在重新检测到手时分配新的ID 。
  • PalmPosition 手掌的位置 他是相对于刚刚设定的leap原点的位置 。
  • frame.hands 会返回一个列表 注意 这是这一帧对象中所有获取到的手的列表
    我们可以通过对这个列表的遍历,来获取到当前场景里面的手的对象。这个建议大家去直观的调试一下 。
  • 更多的调试方式我就不多写了 看看官方的API 这才是程序员应该做的事 。