主要参考b站教程
鉴于网上没有Unity3D和Leap Motion的API的文档,所以自己做一个总结。
B站教程采用的配置是Unity2018.4.7 + Leap unity包4.6.0
我采用的是Unity2020.3LTS + Leap unity包4.6.0,导入最新的Leap Unity包出现导入失败unity could not create directory for asset的问题,原因不明,导入4.6.0也会出现问题,需要更改包中脚本文件
使用时需开启一下两个Control Panel中的一个(且只能开启一个,连接Leap Motion即可
注如果使用的是Ultraleap IR 170亦可,但与Leap Motion添加的unity包文件不同,官网下载即可
在手部位置移动的时候,Hand Model Manager组件的位置对于手部关节点位置信息没有参考价值(因为描绘的是整体的运动),手部关节点的位置通过Attachment Hand中的节点来看(给Hand自定义关节点model也是附着在Attachment Hand上来实现的)。
Attachment Hands中的坐标系(如图)跟LM坐标系不太一样,区别在于各个轴的0点的位置
哔哩哔哩Unity-LeapMotion开发教学视频
关于Core.unitypackage中除Desktop外VR场景,其中infrared Viewer(红外线视图)添加了两个组件以在使用时显示leap motion拍摄到的黑白现实画面
其中,VR模式中,由于LeapMotion一般是装在头盔上来用的,所以需要把lm拿起向下拍摄手部运动,不然就是相反的
Attachment Hands中没有Hand Model Manager,而是Attachment Hands脚本
Hands.unitypackage
将自己的手模部署到Unity中并牵挂LeapMotion的控制组件
及LeapMotion的手的内嵌模型的结构
Interaction Engine.unitypackage
一些官方提供的交互案例,使用Desktop Leap Rig进行演示
其中,提供Leap服务的Leap Service Provider挂载在最高节点上,Hand Model挂载Hand Model Manager脚本,其下手的模型挂载Rigged Hand脚本(Rigged,操纵、蒙皮)
Interaction Manager脚本挂载在Interaction Manager GO上
Interaction Manager脚本中的如图选项控制交互的半径,Multi Grasp Holding Mode在交互物体开启Allow Multi Grasp功能后,使得多只手对同一物体交互有不同效果(弹回另一只手或者直接悬停Interaction Hand在Interaction Hand脚本中,Hover、Contact、Grasping控制一些交互功能的开闭;
在需要与手进行交互的物体上挂载Interaction Behaviour脚本来启动交互功能,Simple Interaction Glow脚本控制交互时闪光的属性,Allow Multi Grasp功能与上述Multi Grasp Holding Mode搭配产生不同效果
测试主悬停功能及看一下脚本文件的编写
在交互物体的Interaction Behavior中没有Ignore Hover时,Simle Interaction Glow中可以设置开启主悬停及主悬停的颜色,以在交互时,给离手最近的物体附以主悬停颜色
Provider GO挂载LeapServiceProvider
Hand Model GO 挂载HandModelManager,使用prefab中的手部模型
给交互物体挂载Interaction Behaviour、Simple Interaction Glow,交互物体可以更改hover颜色,主悬停颜色等
Interaction Manager挂载Interaction Manager,并添加左右手GO挂载Interaction Hand
GO添加Interaction Button脚本,则自动创建RigidBody组件,并添加父物体
Contact Settings中可以选择的有UI和
Layer Overrides设置按下和没有交互的时候当前物体的layer(不知有啥用)
Control Enabled点选是可以控制按钮,不点选是可以交互(比如Hover效果)但不可以按下,如果将整个Interaction Button禁用,则Hover等交互效果也就没有了。
Motion Configuration控制运动的属性,X、Y控制按钮的最小、最大高度,Min Max Height控制按钮的最低最高高度,Resting Height控制停下时按钮的位置在X-Y中的高度比例,Spring Force控制按钮回弹弹力
在存在Interaction Manager的前提下,添加go,挂载Interaction Button脚本,自动生成刚体和父物体(如图中的Button,挂载Interaction Button后,自动生成RigidBody和父物体Button Base),还可以为Button添加Simple Interaction Glow添加基本交互的效果。
需要注意的是,必须在Button或Button的子物体(如图AnNiu)上挂载碰撞体Collider
如图在AnNiu上添加material和mesh(负责场景中交互的按钮实体展示)以及Collider。
注 有一些脚本在Add Component中搜索不到,因为在代码中包含[AddComponentMenu("")]
此条语句,删除即可。
或者可以直接在Button上添加按钮渲染的material和mesh以及Collider,还有Interaction Button和Simple Interaction Glow,就不再需要AnNiu
Motion Configuration控制Slider按下弹起的动画(参考Button中的Motion Configuration
勾选Override Rect Limits,才可以调整下面的两个Axis值,其中参数大概是对于Slider在Panel上的边界、范围的设置,通过Vertical Slide Event可以监听Vertical Value Range的值。
对于上图的Vertical / Horizontal两个监听事件,可以在别的脚本(比如下面的SImple Interaction Glow)中定义Public的方法,然后将脚本(比如Simple Interaction Glow)及对应的方法添加进监听列表,就可以实现在发生相应事件时,调用此方法。
给GO加入Slider Interaction脚本,结构如Button。
推荐使用Transform而不是React Transform
Interaction Callback下四个脚本是基于Core.Unitypackage,Unity Leap的官方API而实现的一些方法。
其中cube(被交互的方块挂载的是Transform Tool),Translate Handle挂载的是Interaction Behaviour和Transform Translation Handle,Rotator Handle挂载的是Interaction Behaviour和Transform Rotation Handle, Transform Translation Handle和Transform Rotation Handle都是继承自Transform Handle。
?
?
?
?
?
手面向用户时,弹出UI界面,使用Attachment Hand标注跟踪的关节,在Palm GO上挂载Simple Facing CameraCallbacks脚本判断手是否面向用户。
Palm UI Pivot Animation负责UI的弹出动画
Hand UI中,Palm UI Pivot Animation 负责动画,Hidden和Visible是UI件的两个状态,Scale变化,
Palm UI Pivot Anchor中的SimpleFacingCameraCallbacks方法通过Palm Forword Animation的 transform.forword和Camera的点积判断相关性(代码如下),判断手掌是否面对相机(but 为什么Palm Forword Animation的transform能代表手的朝向?)
return Vector3.Dot((camera.transform.position - facingTransform.position).normalized, facingTransform.forward) > minAllowedDotProduct;
根据p35-p36讲的Hand的attachment UI,给出具体实现。
?
?
?
?
?
Leap Motion Unity 源文件
Leap Motion Unity Modules,是官方提供的SDK(包括Core、Hand、Interaction)的实现的源文件,包含了一些停止更新和可能被弃用的文件。(已经是四年前的文件了,对应Unity版本是2019.2.17,所以最好使用这之后的版本
目录:Legacy/UIInput/Extras/Cursor3D.js & InteractionCursor
展示了在手上附加球,通过Cursor3D脚本实现远程的抓取多个物体。
通过如下语句获得当前帧的手的骨骼、关节信息
Vector3 Offset = curFrame.Hands[whichHand].Fingers[1].Bone(Bone.BoneType.TYPE_METACARPAL)
.Center.ToVector3()
其中,手指骨骼的示意图如下
BoneType里以枚举类型列出了四个骨骼(拇指只有三个关节
判断Index和Thumb的距离(如果小于30),则认为手指捏合,小球变绿可以抓取物体,给Cursor(小球)附加Spring Joint组件,使其可以抓取多个物体
目录:Legacy/DetectionExamples/Scenes/FingerDetectorDemo
Extended Finger Detector、Finger Direction Detect和Detector Logic Gate实现手势的检测和监听,这三个脚本可以挂载在空节点上完成对手势的控制(最好是挂在HandModel上,但太累赘)。
Extended Finger Detector脚本判断手指是否伸直,以判断手势,并在满足某个手势时,触发OnActivate,离开某个手势时,触发OnDeactivate。其中每个Finger的状态可以被设置为Extended、Not Extended或者Either,其下Min Extended Count设置为Extended的数量,Max Extended Count设置为5-NotExtended的数量。
Finger Direction Detect脚本可以检测任一手指的指向,并在满足条件时触发事件,其中Pointing Type可以设置为指向物体的At Target或者相对摄像头的方向。值得注意的是,此脚本限制了手指指向,如果要指向空间中任意位置,还是需要自己写(比如手指指向某个位置,完成场景的漫游)。
Detector Logic Gate可以关联上述的两个脚本,综合判断一个手势(比如手的姿态和手的指向)。
目录:Legacy/DetectionExamples/Scenes/PinchDetector & PalmDirectionDetector