在ARCore和ARKit中实现多人游戏
在Unite Austin 2017中,Unity的开发人员 Jimmy Alamparambil和Tim Mowrer做了一场演讲《在Unity中使用ARKit和ARCore》。演讲的目地是为了把AR介绍给大家,并给大家展示ARKit和ARCore的各种功能。更重要Unity想让开发者有足够的兴趣为这两个平台开发内容。
下面是一个小时的Unite Austin 2017视频(流量党慎入!)
https://v.qq.com/txp/iframe/player.html?vid=o0501q3n89t&width=500&height=375&auto=0
请注意:演讲中用到的例子和代码都是试验性的。所用到包也不会得到Unity的官方支持,在ARCore或是ARKit上之后的任何改动都可能让这个包失效。
开发者们的第一个需求,他们想要编写出能够跨平台使用的代码,这样能便于同时在ARKit和ARCore上,或是其它未来可能出现的平台上使用。这个需求与Unity的核心价值十分相符,我们就是要实现统一化开发,让开发者能够一次编码、多平台部署。为了实现这个目的,我们开发了一个试验性的API,并希望这个API能演变为集成的跨平台API。
第二个需求是如何解决AR中显示缩放内容的问题,以及第三个需求是如何使用Unity中现成的功能来实现多人游戏功能。
这次演讲中,我们回应了以上的三个需求。而在这篇文章中,我们希望为你带来演讲中的更多细节,帮助你使用演讲中的示例代码。
下载示例代码
你可以访问GitHub下载演讲中的示例代码,下载地址请访问文末。
要想使用ARKit或ARCore,以下条件必须全部满足。
Unity 2017.2.0f3或以上版本
Unity ARKit插件 – 可以在BitBucket或是Asset Store资源商店获取
Unity ARCore插件请参考《Unity支持ARCore,为移动AR再下一城》一文中的步骤安装
ARInterface
开始之前需要特别强调,我们在Unite Austin中使用的ARInterface仍处于试验阶段。我们仅用了二周时间开发这个工具,旨在为这次演讲制作出一些跨平台的演示项目,所以并没有考虑它与当前Unity版本或现有的API是否完全兼容。
在Unity内部,我们已经在为多个AR平台开发原生的跨平台集成工具。在官方正式工具发布前,这个C# API将是一个用于开发ARCore和ARKit跨平台应用的有用工具。
在为ARKit或是ARCore开发AR应用时,通常要用到不同平台的API和组件。ARInterface则将多个平台的一些共同点抽象化为一个单独的层面,这意味着若是开发者在代码中调用的是ARInterface的API,那么ARInterface可以确保开发者的代码将会调用到正确的相关平台的API。
目前的ARInterface可以在ARKit和ARCore上进行跨平台工作,但通过类似的方法,我们也可以用它来支持其它拥有类似功能的AR平台。
当前可用的API
现在我们打开项目中的ARInterface.cs,看看这个接口用到了哪些API。下面是关于这个接口的介绍和使用方法。
首先我们用这些API来控制AR会话的开启和关闭:
public abstract bool StartService(Settings settings);
public abstract void StopService();
Settings参数能让你启用会话中的创造点云(point cloud)、光照估算和平面检测功能。
下一个是AR的基本功能:世界跟踪。这个功能用于跟踪现实世界中AR设备的具体位置和空间方位。
public bool TryGetPose(ref Pose pose);
这里的Pose参数用来确定所用设备摄像头的位置和旋转角度,它通常用来让Unity的摄像机跟着真实摄像头移动。
下面这些是针对平面检测的事件代理:
public static Action<BoundedPlane> planeAdded;
public static Action<BoundedPlane> planeUpdated;
public static Action<BoundedPlane> planeRemoved;
这些调用能让你跟踪AR会话中被检测到的平台,了解它们何时被添加、更新或移除。
要想把现实场景添加到AR中,你需要将设备摄像机的画面渲染为编辑器场景中摄像机的背景:
public abstract void SetupCamera(Camera camera);
把你需要显示视频背景的Unity摄像机作为参数传入,系统会自动完成设置。
对于背景渲染,我们还需要进行显示变换,它能让着色器根据设备的旋转角度和屏幕尺寸来旋转背景纹理:
public abstract Matrix4x4 GetDisplayTransform ();
这个调用用于获取被检测到的点云:
public abstract bool TryGetPointCloud(ref PointCloud pointCloud);
PointCloud参数包含一个Vector3列表,这个列表会记录我们在世界坐标系中各个点的位置。
AR平台通常会返回场景中的预估光照:
public abstract LightEstimate GetLightEstimate();
LightEstimate(光照估算)参数里包含了ambientIntensity(环境强度)参数和ambientColorTemperature(环境色温)参数。
有些情况下,你需要从现实环境中镜头捕捉到的画面来得到画面的像素值,这类情况下,你需要使用:
public abstract bool TryGetCameraImage(ref CameraImage cameraImage);
CameraImage变量包含了捕捉到的实际像素,这些数据是从CPU获取的。
ARKitInterface和ARCoreInterface
这部分介绍用ARInterface来分别处理ARKit和ARCore平台的具体实现。这些实现使用了底层插件来完成所需功能。阅读这部分可以明白如何将这些方法应用到其它平台上。
AREditorInterface: ARInterface
我们也可以用ARInterface做一个新功能:在Unity编辑器里面使用ARInterface来模拟出一个AR环境。在这个例子中,我们模拟的AR环境生成了两个平面:一个在一秒后生成,另一个在两秒后生成。
它还能生成由20个随机点构成的点云。这个例子中的代码在AREditorInterface.cs里,你可以根据需要模拟出自己想要的拥有不同细节的AR环境。
现在我们可以与这个环境展开互动,就像真的通过设备在里面移动一样,我们还可以据此进行调试和迭代,因为这个环境就在编辑器中。要想在环境中移动摄像头,使用WASD键即可。要想调整摄像头方向,按住右键移动鼠标。
由于我们是在编辑器中,可以通过检视窗口改变任意GameObject参数,并马上看到改变结果。我们还能修改代码,因为在修改完代码以后可以瞬间完成编译,所以我们可以立即重新运行修改后的场景。除此之外,我们还能在代码中设置断点,检查为何有些地方没按预期实现。
在开发新示例和从其它平台移植示例时,我们发现这个工具十分有用:使用它可以进行快速迭代,甚至不需要AR设备!
ARRemoteInterface: ARInterface
和ARKit插件同时发布的一个最受欢迎的工具是ARKit Remote。(https://blogs.unity3d.com/2017/08/03/introducing-the-unity-arkit-remote/)
这个工具有二个部分:一个是安装在AR设备上的远程应用,另一个是放在场景内的组件。后者将从远程应用收集ARKit数据,然后在编辑器里生成模拟环境。
这能让开发者在编辑器中迭代并调试,功能类似EditorInterface,但和EditorInterface不同的是,这个工具能从现实环境中获取真实的数据。
ARKit Remote非常受到开发者们的欢迎,这意味着当ARCore预览版发布时,开发者们会强烈建议得到用于ARCore的类似工具。
有了跨平台使用的ARInterface后,开发用于ARCore的类似工具会更简单,只要通过端口对现有的ARKit Remote加入相应功能即可。
若要使用这个工作流程,首先你需要构建RemoteDevice场景(在Assets/UnityARinterface/ARRemote目录下可以找到),然后将其安装到支持ARKit或ARCore的设备上。
构建时,要记得在Build Settings(构建设置)中勾选“Development Build”(开发构建)选项,这样会启用PlayerConnection机制,用于远程应用和编辑器的数据沟通。
接着需要把迭代的AR场景在编辑器中打开,并在ARRoot GameObject上新建一个ARRemoteEditor组件。
如果在同一GameObject上有ARController组件,则禁用该组件。现在运行装在设备上的远程应用,用控制台的“Connected Player”菜单连接设备。在编辑器中按下”Play”按钮,然后你便会得到如下的结果。
按下屏幕顶部的“Start Remote AR Session”按钮,然后AR设备会将AR数据发送到编辑器中。现在就能使用从设备得到的真实AR数据,并在编辑器中迭代了。
移植示例
我们利用ARInterface将几个ARKit示例移植到了ARCore平台上。此外,这样做还让我们能使用AREditorInterface和ARRemoteInterface。实际上,这些示例的移植简单而快捷,因为我们能用AREditorInterface在编辑器中对它们进行快速迭代。
Focus Square示例
在Apple的AR Human Interaction Guidelines中,有个关键组件是指示符,用来确定在环境中放置虚拟物品的位置。Focus Square便是这个指示符的一个实现。
移植这个示例到ARInterface的过程比较直接,因为它不会涉及太多平台特定代码,除了HitTest。
所以我们决定对生成平面游戏对象使用光线投射取代HitTest。这将给那个平面实现HitTest的效果,而且还能在编辑器上使用。
AR会话和摄像头的其它部分由ARController来设置,ARController和其它对AR场景进行设置的代码放在一起 。
AR Ballz示例
Unity AR Ballz是个有趣的演示,用于展示在AR中平坦表面的物理交互效果。这个示例包含两个模式。
第一个模式下,当你在屏幕上点击平面时,被点击到的平台上会创建球对象。
第二个模式下,当你在屏幕上点击平面时,球会移开。
在移植这个示例时,由于我们只想要对平面使用HitTest功能,我们用之前提到那个适合编辑器的插件替换了用于定位并移动球对象的HitTest。
我们所做的另一个改变,是使用手指位置的力向量制造交互效果,而不是使用碰撞的动态效果,这样球的移动效果更好。这个示例让我们知道,EditorInterface可以方便地对检视窗口中的参数进行迭代。
你可以在编辑器中尝试这些示例,在Remotes或实际的ARKit和ARCore设备中也可以。我们期待能使用ARInterface移植更多的示例。
缩放AR中的物品
我们谈了缩放物品还讨论了怎样在不调整物品本身大小的情况下,使用一些摄像机技巧来实现类似效果。我们展示了两个调整大小的方法,其中一个方法使用了一个摄像机,另一个方法则使用了两个摄像头。
你可以在Assets/UnityARInterface/Examples/ScaledContent目录下了解单个摄像头解决方案的实现。
实现多人游戏
实习多人游戏需求来自游戏开发者,他们想要实现不同设备在同一个空间中玩同一款游戏。为了解决这个问题,我们要制作一个多人游戏来实现它ARInterface,为这个示例的开发提供了很大的帮助。
我们使用了Asset Store资源商店中的《TANKS! Networking Demo》项目。因为这个项目实现了多个移动端设备间运行的多人游戏。但这项目唯一缺少的功能就是AR功能,用于在不同设备上一同体验AR效果。
这个项目通过以下流程运行:
Lobby Scene(大厅场景)用于匹配不同设备的用户,然后将匹配到的玩家连接至Main Scene(主场景)下一同游玩。
为了进行修改,我们先去除了主场景中的CameraRig对象,因为我们打算创建一个由AR设备控制的摄像头,而不是由坦克移动来控制。然后我们在原有流程之前加入新的场景。
我们在AR Setup Scene(AR设置场景)中设置了AR会话和AR摄像头。然后我们将控制权交至Lobby Scene,确保在我们载入后续场景时,AR会话和摄像头仍会保留在场景中。
AR Setup Scene通过平面检测功能来确定游戏位置。两个设备都会对着相同的桌面位置,然后用其中心点来确定游戏的水平面。由于我们的两个设备都会用到现实中的桌面中心和方位来同步各自的坐标系统,共享水平面会根据两个设备的画面在同一位置生成。
然后我们使用了在ScaledContent(缩放AR中的物品)部分介绍的机制,根据平面大小和Tanks!中使用的平面大小,确定我们所用水平面上物体的大小。然后我们将这个大小设定应用到Tanks!的水平面上,显示给两位玩家。我们还做了些改动,让我们能通过屏幕点击和拖动直接控制游戏对象。
资源下载
ARKit下载
Bitbucket:https://bitbucket.org/Unity-Technologies/unity-arkit-plugin
Asset Store:https://www.assetstore.unity3d.com/en/#!/content/92515
ARInterface示例代码
https://github.com/Unity-Technologies/experimental-ARInterface
TANKS! Networking 示例
https://www.assetstore.unity3d.com/en/#!/content/46213
总结
我们希望这次演讲和相关代码能启发你开发更多新内容,比如新的特性或是用于AR应用的交互功能。后面我们还将为大家分享更多新功能及相关教程在Unity官方中文社区(unitychina.cn),请保持关注!
推荐阅读
使用Unity在手机上实现移动Inside-out VR追踪
近期Unity官方活动
11月,Unity教育峰会,广州、桂林、济南、武汉站报名火热进行中。
Unity Connect火热征文中,赶紧来分享你的Made with Unity作品吧!
点击“阅读原文”进入Unity官方中文社区!