您当前的位置:首页 VR开发 Unity 正文

LeapMotion的Unity开发教程:基本概念和手的预制件

查看: 3285| 评论: 0 2016-9-27 10:52 AM| 发布者: PeckBang

最近用Leap Motion + 国产的3Glass眼镜构建了房地产、数字矿山的一些应用,感觉这是很经济的一个VR架构方案,比用Oculus和HTC的硬件要省钱得多,并且效果也不错。

在行业VR应用中,其实重在培训教育、生产安全的仿真演练上,更多地通过一些UI互动、基础性的手势(比如开关设备、拾起灭火装备等)来进行交互,这些并不一定需要非常昂贵的激光定位设备、复杂的硬件套件才可实现,而手势识别在未来也是一个趋势。

所以将一些开发积累整理下来,希望不断地能在这个领域中学习领会,最终能为行业客户创造一些实用的价值。  

一.  安装

1.      打开官网:https://developer.leapmotion.com/get-started

2.      先要下载和安装LeapMotion的驱动程序

         

注:我买的是二代Leap Motion,所以在Win10下 不支持V2 Desktop的开发驱动,选择左面的。(注意是开发驱动,而非App应用)

                 

我下载的最新版本是3.1.2,解压后如下图。


运行EXE文件,根据提示安装驱动,实际上这将安装了一个驻留程序在系统托盘中,并且生成一个自动启动的系统服务Leap Service,在控制面板中可查看它,当遇到Leap Motion不工作,或者托盘中图标显示黑色时,可检查一下这个服务是否正常。

驱动程序与LeapService通讯,读取硬件层面3D摄像头跟踪的手势数据,上层类的应用(如Unity,虚幻4,Java等)则与驱动程序(C++写成)通讯。

安装成功后,能看到LeapMotion两个摄像头和中间LED灯都正常亮起,表明处于工作状态,这时可用自动安装的Leap App Home应用来测试一下,通过它还可下载一些官方的例子。

3.      下载准备好各类Unity包

https://developer.leapmotion.com/unity下载所需的包。


其中CoreAssert是核心包,其他都是封装好的各类功能包,在实战篇中会介绍。

二.  基本概念

1.   坐标系统

Unity使用左手坐标,LeapMotion使用右手坐标(所以,Z轴是相反的)。

Unity以米为单位,LeapMotion使用毫米。LeapMotion配备的Plugin脚本内部对坐标系统进行了转化,即将单位和坐标转化为Unity的标准。

 

注意:在Unity中,一定要从LeapServiceProvider中获得Frame对象,否则在帧中的数据(TrackingData)将还使用Leap的坐标系统。LeapServiceProvider解析了Scaling,Rotation,Translation的变换.

2.   手势跟踪

LeapMotion使用了光学传感器和红外光组件。传感器的FOV为150度。顶部0.03~0.06米为有效的跟踪范围。


最佳的工作环境是可产生清晰的、高对比度对象轮廓的光照环境。

 

HMD模式下(头盔绑定的模式 ),跟踪算法被优化成对不同的视角下识别手势(大概的意思可能是,你头盔多动动,识别得更好一些),比放在桌面固定不动要更好一些。

 

3.   手(Hand Assert)

(1)表示方法

在预制件目录下,分成图形(图元)和物理两组脚本和预制件,可以用其中各一来组合表示手。这一处一定要理解,官方的Unity包里给了一些场景例子,可以研习一下。

从概念上手被区分成Graphic和Physic两种组件构成,前一即是图元,主要是呈现手的外观,后一主要表现手的物理特性(如刚体、碰撞)。

也可以没有物理组件,这样就不能产生物理特征了。

(2)创建手的方法

有几种创建手的方法:

  •  单独创建手的不同部位,比如手掌、胳膊、手指;
  •  创建绑骨骼的Mesh,驱动关节和骨骼来表示手的动作;
  •  用脚本编写来表示手的图形(即完全用脚本来绘制)。

(3)一个例子

下图是一个典型的手的例子,一个HandController下挂4个子对象,分别是图元左右手,物理左右手。


三.  创建你自己的手Prefab

注:跟着官方例子创建一个手,可能并不是很实用,但有助于理解手的预制件和原理组成。

你可以创建类似于已提供的Unity包里的手预制件,用你自己的图形来表示手,同时定制自己的手的行为(基于已提供好的代码)。

我们要创建的这种手称为“离散手预制件Discrete Hand Prefabs”,意思是手上每个部位都是单独的Game Object,都有其单独的位置和方向信息。在Core assert 包里,机器人的手即是这样的“离散预制件”。下面介绍了通过使用Unity自带的几何体(圆柱、圆)来创建Prefab。

  • 每一个图形元素都放在一个空对象下。手和手指的脚本负责更新空对象的Transform。每个图元的Local Transform的位置和方位依从于父对象。
  • 移除图形手上的所有碰撞体,否则将引起RigidHand的碰撞反弹。
  •  通常你不需要同时拥有关节和骨头。他们不是相互独立的。本教程中我们同时将关节和骨头加进模型中只是为了演示他们是如何工作的。
  • 类似的,你的模型也不必同时具有掌骨和手掌。掌骨是被手掌包围的,并且不能单独地动作。本教程同时具有二者(为了演示)。
  •  对手模型使用真实世界的尺寸。手和手指的脚本不能独立识别相关部位。整体的Scale被赋值成LeapHandController对象的scale(因为是必须挂在HandController下)
  • 由于采用了非常抽象和对称的设计,所以像在本教程中,能使用同样的Prefab表示左手和右手。但大多数的模型还是应使用不同的prefab表示左右手,这样能更好地调整Local Transform。


首先,我们需要创建一个手指的Prefab,并且使用它来创建手Prefab。

创建手指Prefab

1.     创建一个场景.

2.     新建一个空对象,命名KnobbyFinger

3.     创建骨头

1)     新建一个空对象到KnobbyFinger下,命名Metacarpal  (掌骨)

2)     新建一个CylinderMetacarpal,命名Tube.在创建你自己的手时,将此Cylinder替换为你自己的图形对象(或Obejct

3)     移除碰撞体组件,否则RigidHand碰撞体将会与它反弹。

4)     设置X Rotation90

(最好设置成Top视野来观察)

5)     Tube XZScale设置成0.0033毫米)。之所以这样设置,是因为要使用带皮肤的骨头,真实的手指要更胖一些。

6)     设置Tube YScale0.03434毫米)。这个决定了手指的长度。

尺寸必须使用真实世界的,转化为米。Y的长度应为68mm的一半,这是因为Cylinder2个单位高。所以我们要Scale缩减50%.

7)     复制Metacarpal,命名ProximalTube Y-Scale设置为0.02

8)     再复制Metacarpal,命名IntermediateTubeY-Scale设置为0.01

9)     再次复制Metacarpal,命名DistalTubeY-Scale0.007

4.     创建关节

记住:你不必都需要骨头和关节

1)     新建空对象到KnobbyFinger,取名MetacarpophalangealJoint(掌指关节)

2)     新建一个圆到关节,取名Knob.

3)     移除碰撞体。

4)     Knob所有的Scale设置成0.011厘米).

5)     复制MetacarpophalangealJoint更名为ProximalinterphalangealJoint.

6)     复制MetacarpophalangealJoint更名为DistalinterphalangealJoint.

6.     增加SkeletalFinger 脚本组件到KnobbyFinger

7.     拖动每个关节和骨头到脚本中的相应变量处。

具体如下:

Bones:

o  0 -Metacarpal

o  1 - Proximal

o  2 -Intermediate

o  3 - Distal

Joints:

o  0 - MetacarpohalangealJoint

o  1 -ProximalinterphalangealJoint

o  2 -DistalphalangealJoint

8.     将KonbbyFinger做成预制件。

创建手Prefab

(创建好手指Prefab后)

1.     创建空对象,取名KnobbyHand.

2.     增加SkeletalHand 脚本到 KnobbyHand.

3.     脚本变量Handedness设置成“Either.” (如果你的手是不对称的,设置成 “Right” or “Left”.)

4.     拖动5个KnobbyFinger Prefab到手中,命名为:Thumb, Index, Middle, Ring, and Pinky.

5.     对于每个手指,设置Finger类型为相对应的类型(SkelatalFinger脚本组件中)。

6.     拖动手指到KnobbyHand 的SkeletalHand 脚本中相应的Fingers变量上.

Finger element order:

o  0 - Thumb

o  1 - Index

o  2 - Middle

o  3 - Ring

o  4 - Pinky

7.     拇指是特殊的,没有Metacarpal. 因此,编辑Thumb,在bone数组中移除bone( element 0 ) . 删除Metacarpal子对象.

8.     增加手掌Add the palm:

如果没有图形元素,你可以在KnobbyHand的SkeletalHand脚本变量Palm,wrist,forearm先留为空白。手掌也可通过RigidHand来表示,如果你不使用palm,你可以修改RigidHand的副本,但要移除rigid body和collider。

1)    增加一个空对象到KnobbyHand.取名Palm.

2)    增加一个Cylinder Palm.取名 Disc.

3)    移除Collider.

4)    设置Disc scale (.085, .0015, .085)..

5)    拖动PalmSkeletalHand脚本的Palm变量中

9.     增加手腕:

1)    增加一个空对象到KnobbyHand,取名Wrist.

2)    增加一个圆到Wrist.取名 Ball.

3)    移除Collider.

4)    设置Ball scale(.03, .03, .03).

5)    拖动WristSkeletalHand脚本WristJoint变量中.

10.  增加胳膊

1)    增加一个空对象Arm.

2)    增加一个CylinderRod.

3)    移除Collider.

4)    设置Rodx rotation为: 90.

5)    设置Rodscale(.02, .12, .02).

6)    拖动 ArmSkeletalHand脚本的Forearm

12. KnobbyHand创建为prefab.

KnobbyHand的结构应为下图所示:

测试你的手

1.     新建一个LeapHandController prefab到场景中,以便交互区域是在摄影机的FOV内。

2.     设置如下层次结构

3.     LeapHandControllerHandPool中设置:

.

4.     运行关卡,观察你的手

如果RigidHand组件在Scene窗口中可见,但抖动或反弹,确保你移除图元手部位的所有碰撞体。

如果手指重叠或者移动在一个手指的控制下,检查手指SkeletalFinger 脚本的手指类型设置。

如果你的手混杂成一大团的乱糟糟样子,那是每个子元的Scale设置的太大了,记得Unity的单位是1米,一个典型的手宽度是8.5厘米(或者表示成Unity transform的Scale是0.085)。如果想使手更大一些(在游戏里看),增大LeapHandController的Scale.

52VR.COM微信扫一扫
52vr公众号
专注于VR的学习、开发和人才交流

52VR开发交流

相关推荐

已有 0 人参与

发表评论

您需要登录才可以回帖 登录 | 立即注册

手机版|VR开发网 ( 津ICP备18009691号 ) 统计 网安备12019202000257

GMT+8, 2020-10-22 02:37 AM

返回顶部