Leap Motion Using Unity3D——环岛跑车篇

一. Leap Motion简介

Leap Motion作为一款体感传感器,通过立体视觉捕捉红外图像信息并产生手掌在三维空间中的相关信息。下面会结合示例来说明Leap Motion采集的模型数据在跑车游戏中的应用。翻译来自Pierre Semaan的博客“Leap Enabling the Unity3D Car Tutorial”,然后对有关联的代码和操作注意事项加以说明。

二. 软件要求

1. Unity3D

官方给的选择为Unity 5 Pro或者Unity 5 Free,不过笔者用的是Unity 4.6;

2. 跑车教程

在Unity3D的资源商店中搜索”Car Tutorial“,然后在Unity3D中免费下载并导入资源即可;

3. Leap SDK

在Leap Motion的官网上下载最新版本的SDK。如果下载不了或者回到前一个界面,可以尝试换浏览器下载。

4. Leap Motion输入脚本

选用Pierre Semaan提供的pxLeapInput.cs。

三. 操作步骤

1. 创建新的工程

新建Unity3D工程时,导入Car Tutorial.unitypackage包。

2. 确保CompleteScene场景正常工作

CompleteScene场景存放在Scenes文件夹下,双击打开场景后可以俯视看到环形跑道。不过由于Unity 3版本的跑车游戏转到Unity 5后提示shader有问题,于是岛外的背景颜色看起来有些违和。运行游戏,按上下左右键可以控制跑车则说明游戏正常。

3. 复制CompleteScene

CompleteScene复制后重命名为LeapCompleteScene,这样可以备份源文件并开始大胆地实验。

4. 在Assets目录下创建Plugins文件夹

5. 复制Leap文件至Plugins文件夹和游戏文件的根目录下

复制Leap.dll和LeapCSharp.dll至游戏文件夹的根目录下,注意两个文件是有不同操作系统的版本。然后复制LeapCSharp.NET3.5.dll至Plugins文件夹下。

6. 复制LeapUnityExtensions.cs至Plugins文件夹

下载LeapUnityExtensions.cs然后复制进Plugins文件夹。

7. 复制pxsLeapInput.cs至Plugins文件夹

下载pxsLeapinput.cs文件并复制到Plugins文件夹。脚本必须在Plugins文件夹下因为后面我们需要在javascript脚本中参考它,并且它需要 先编译这样javascript引擎才能看见它。
a)(可选)检查pxsLeapInput.cs脚本
它是一个单例并且包含易于从最近的Update中获取图像帧和手的属性。关键函数为GetHandAxisPrivate:
private static float GetHandAxisPrivate(string axisName, bool scaled)
{// Call Update so you can get the latest frame and handUpdate();float ret = 0.0F;if (m_Hand != null){Vector3 PalmPosition = new Vector3(0,0,0);Vector3 PalmNormal = new Vector3(0,0,0);Vector3 PalmDirection = new Vector3(0,0,0);if (scaled == true){PalmPosition = m_Hand.PalmPosition.ToUnityTranslated();PalmNormal = m_Hand.PalmNormal.ToUnity();                PalmDirection = m_Hand.Direction.ToUnity();}else{PalmPosition = m_Hand.PalmPosition.ToUnity();PalmNormal = m_Hand.PalmPosition.ToUnity();PalmDirection = m_Hand.Direction.ToUnity();}switch (axisName){case "Horizontal":ret = PalmPosition.x ;break;case "Vertical":ret = PalmPosition.y;break;case "Depth":ret = PalmPosition.z ;break;case "Rotation":ret = -2 * PalmNormal.x ;break;case "Tilt":ret = PalmNormal.z ;break;case "HorizontalDirection":ret = PalmDirection.x ;break;case "VericalDirection":ret = PalmDirection.y ;break;default:break;}}if (scaled == true){if (ret > 1) {ret = 1;}if (ret < -1) {ret = -1;}}return ret;
}
pxLeapInput被定义为一个静态类;定义了一个Leap名称空间中的空Controller对象m_Controller,空Frame对象m_Frame和空Hand对象m_Hand。
构造函数中用new创建了一个Controller对象,如果创建失败,则返回Errors字符串提示。
定义Frame函数返回m_Frame,定义Hand函数返回m_Hand。
在Update函数中,首先判断m_Controller是否创建成功,如果创建成功,则将当前帧传给上一帧(这句没起作用),用Frame函数返回当前帧m_Frame;如果当前帧不为空,则说明检测到手,将当前帧的类中的Hands数组中索引为0的部分赋值给m_Hand(说明只是用到单手控制)。
        在GetHandAxisPrivate函数中,函数输入包括轴的名称axisName(字符串)和缩放标志位scaled(布尔型)。首先调用Update函数获取当前帧和当前帧中索引为0的手;如果布尔型变量scaled值为真,则掌心位置使用ToUnityTranslated函数获取,掌心方向量和掌心方向用ToUnity函数获取,否则掌心位置用ToUnity获取。

(1)如果轴名称为”水平“,则返回掌心位置的x轴值;
(2)如果轴名称为”垂直“,则返回掌心位置的y轴值;
(3)如果轴名称为”深度“,则返回掌心位置的z轴值;
(4)如果轴名称为”旋转“,则返回掌心法向量的x轴值的-2倍;
(5)如果轴名称为”倾斜“,则返回掌心法向量的z轴值;
(6)如果轴名称为”水平方向“,则返回掌心方向的x轴值;
(7)如果轴名称为”垂直方向“,则返回掌心方向的y轴值。

如果scaled为真,将轴值截断至-1到1之间。

8. 在Car.js中调用pxsLeapInput

GetHandAxis函数调用GetHandAxisPrivate函数时,scaled值置为真,所以返回值为1且掌心位置调用ToUnityTranslated函数。为了用Leap Motion输入覆盖键盘输入,需要在GetInput函数中修改。
if(LeapEnabled == true){throttle = pxsLeapInput.GetHandAxis("Depth") * forwardScale;steer = pxsLeapInput.GetHandAxis("Rotation");print("Throttle: " + throttle.ToString() + "Steer: " + steer.ToString());
}
else{throttle = Input.GetAxis("Vertical");steer = Input.GetAxis("Horizontal");
}
和GetAxis类似,GetHandAxis的返回值变化范围为[-1,1]。同时为了避免直接覆盖键盘控制,添加LeapEnabled标志位选择Leap Motion输入是否使能。为了调整前进速度,添加forwardScale变量避免跑车加减速过快或过慢带来的不适。
public var LeapEnabled : boolean = false;
public var forwardScale : float = 0.4;

9. 使能Leap Motion输入

scaled变量创建时默认值为假,所以需要将Car物体右侧对应的脚本Car.js下的公有变量scaled打勾(置为真)。运行游戏即可用Leap Motion控制游戏。游戏操作的正确方式为:手心和手背以手臂为轴逆时针旋转为左转,反之顺时针旋转为右转,旋转时的静态角度代表跑车转动的幅值。手掌置于Leap Motion前方则第一视角与车头前进的方向相同,反之置于后方则第一视角与车头前进的方向相反(车尾前进,车体后退)。

10. Leap Motion输入介绍

为了更好地用Leap Motion控制游戏,至少要知道我们用什么样的手势运动替换掉了水平轴和垂直轴的输入。所以,下面简单介绍用到的帧和手的数据结构以及手的数据结构对应的手的属性。
(1)数值单位
距离:毫米;时间:毫秒;速度:毫米/秒;角度:弧度。
(2)帧

帧的基本实体包括Hand,fingers和tools。controller.frame()获取当前帧;controller.frame(n)获取上n帧;frame.id()获取当前帧的整数型ID;Leap::Listener类中检测新帧到来的回调函数为onFrame(controller);frame.hand(id),frame.finger(id)和frame.tool(id)为获取当前ID的手,手指和工具数据。

(3)手
获取手的方向时也用到x,y和z轴坐标,虽然经过ToUnity函数的转换(不清楚什么意思),但是我猜得到的还是roll,pitch和yaw值。不过用到手的方向时还是调用官方提供的roll(),pitch()和yaw()比较妥。手掌和手指的位置是相对于Leap Motion中心的全局坐标系的位置,每个地方有不同的RPY方向。有时虽然调用的函数相同,但继承函数所在的基类的对象不同,比如direction函数。P.S.下图为C++中的函数,仅供说明使用。

结语

本篇主要描述如果用Leap Motion的输入来替换键盘的方向键,并没有深入Unity3D生成的游戏的代码,不过应该很多人会比笔者更了解Unity3D。鼠标和键盘对于二维平面操作要优于Leap Motion,因为Leap Motion在控制时很难令其中一维坐标保持不变,对于手来说很容易疲惫;而且二维操作在空中显然费力不讨好;但是对于三维平面操作,鼠标和键盘一定要结合起来用才行,Leap Motion只是提供了一种更加自然的操作方式。所以,在虚拟环境中绘制手模型,并以人眼为反馈作三维空间操作是可选的比较合理又自然的交互方式。

Leap Motion Using Unity3D——环岛跑车篇相关推荐

  1. Unity3D中使用Leap Motion进行手势控制

    Leap Motion作为一款手势识别设备,相比于Kniect,优点在于精确度. 在我的毕业设计<场景漫游器>的开发中,Leap Motion的手势控制作为重要的一个环节.以此,谈谈开发中 ...

  2. 【新手入门】全网最全Leap Motion技术总结

    不好意思有点标题党了hhh~ 本科毕设使用了Leap Motion完成了一个双手交互体验的小程序,在查阅相关资料时发现网上的资料良莠不齐.不够系统,常常是花费了很多精力搜集资料却得不到想要的答案.正好 ...

  3. Unity3D与Leap motion连接学习记录

     https://www.leapmotion.com/partnerships (Leapmotion官方网站) 把这个leapmotion手势识别相机看一下,这个开发互动非常方便,有开发sdk ...

  4. Leap Motion开发(三)Unity3D API总结

    主要参考b站教程 鉴于网上没有Unity3D和Leap Motion的API的文档,所以自己做一个总结. 配置 B站教程采用的配置是Unity2018.4.7 + Leap unity包4.6.0 我 ...

  5. 基于Leap Motion设备及Unity3D引擎的自定义手势识别

    1.Leap Motion 官网下载SDK并导入Unity3D,官网地址:https://developer.leapmotion.com/  本次测试适用unity版本为2017.1以上 下载内容: ...

  6. Leap Motion 之Unity 开发指南(一. 基本概念与制作手预制件)

    LeapMotion 之Unity开发指南(一.基本概念和手的预制件) [序言] 最近用Leap Motion + 国产的3Glass眼镜构建了房地产.数字矿山的一些应用,感觉这是很经济的一个VR架构 ...

  7. Leap Motion不会再出独立的控制器二代

    Leap Motion的使用者应该比较期待新版的Leap Motion,我也是其中之一.实话说Leap Motion精度不够好,也就是说在根据深度信息获取手指位置的过程中,手指的遮挡会造成Leap M ...

  8. 十大最佳Leap Motion体感控制器应用

    十大最佳Leap Motion体感控制器应用 Leap Motion Controller也许还没有准备好大规模的发售,但是毫无疑问,这款小巧的动作捕捉器是我们见过的最酷的设备之一.这款设备的硬件配置 ...

  9. 【VR】Leap Motion 官网文档 HandModel(手部模型)

    前言: 本系列译文是为迎合Unity VR的热潮与大家的学习需要,推出的针对Unity方向的Leap Motion官方文档中英对照翻译. 本篇为第六篇 <HandModel(手部模型)> ...

  10. 基于Leap Motion的智能灯光控制系统

    事先声明,本文涉及到的所有代码都是我毕业设计的内容,请勿转载. 准备工作 Arduino IDE.Processing.8*8 WS2812B.Leap Motion 其中,Arduino需要安装Ad ...

最新文章

  1. Android简单手势滑动的识别
  2. 单机版五子棋java功能_java实现单机版和网络对战版五子棋程序
  3. 关于VS2013下制作和使用静态库和动态库
  4. STM32F103ZE单片机在WWDG窗口看门狗的EWI中断中喂狗导致系统复位的原因及解决办法(中断函数重入问题)
  5. 前端调试、兼容、适配指南与工具分享
  6. 15名优秀女科学家拟获重量级荣誉
  7. Fresh for Mac(文件管理软件)
  8. python 后10个元素_10 行 Python 代码写 1 个 USB 病毒
  9. 如何在PHP里面连接数据库?
  10. java高级之注解详解
  11. python文件和路径操作
  12. svn 命令行_Ubuntu下Subversion(SVN)的快速安装与配置
  13. 特征选择的基本方法概述
  14. dependencyManagement 失效
  15. GET 请求参数过大导致HTTP错误码 414 / 500 的问题
  16. C#实现Omron欧姆龙PLC的Fins Tcp协议
  17. 【支付】第三方支付收单机构
  18. 再聊聊Python中文社区的翻译
  19. 2021-2027年全球与中国彩色隐形眼镜行业市场前瞻与投资战略规划分析报告
  20. DevC++实现代码高亮复制进word

热门文章

  1. 目前有哪些支持独立模板的多城市分站的网站程序?
  2. mysqldump单个库导出_mysqldump备份所有数据库,恢复单个库的场景预演
  3. [转帖】离婚了我们先同居
  4. UDS(八)应用层 22/2E
  5. Android事件体系全面总结+实践分析,完整版开放下载
  6. MySQL 8.0.28 数据库完整备份及恢复以及binlog日志增量恢复
  7. 2021牛客暑期多校训练营1(补题)
  8. vue ElementUi表中列、表尾合计保留两位小数
  9. 域控制器失去信任关系问题处理
  10. 【数据结构】:二叉树,线索二叉树,排序二叉树,AVL树