本帖最后由 wzyxkk 于 2017-8-7 21:53 编辑
ARKit and Unity
iOS11新版本的主要更新之一是ARKit。 到目前为止,IOS 11尚未公开发布,但有一个beta版本供开发者使用。 如果您网上看到一些有趣的视频Demo,展示了一些功能...
AR已经存在了一段时间,但是在旧版本的IOS中,您不得不依靠计算机视觉库或其他的第三方SDK来进行开发。一种常见的方法是基于标记的跟踪(图片识别)。
基于标记的AR通过识别和跟踪预定义的图像来工作。它将3D世界缩放并对准标记,并将3D对象绘制在前景(叠加于摄像机画面上)中。
ARKit只支持6S +和更新的型号,但如果您要构建一个应用程序来支持所有型号,这里有一些库可以检出基于标记的AR;
ARKit ARKits新技术基于视觉惯性测距,它可以通过在移动时在相机视图中查找和跟踪点来工作。 与来自手机的运动传感器数据一起,可以保持您在房间中的位置的近似值。从这个数据可以提取场景中的水平面,特征点。 要识别特征点,视图中必须有足够的视觉信息。图像中的对比度越大,查找点就越容易。例如白墙将不具有特征点,而黑色和白色的网格将具有多个点。
ARKit没有任何深度感测技术。 它不能遮挡对象,这意味着对象总是绘制在视频图像的前面。 有人猜测,新的Iphone将有一个深度感应摄像头,如Tango手机和Hololens。 他们都创建了一个用于遮挡和碰撞检测的环境的空间网格,用于真正沉浸式的效果。
在设计应用程序时要注意事项… - 平面跟踪在检测平面边缘时不是很准确,并且在手机移动几秒后才开始检测。跟踪功能开启时比较耗电,不要时最好关闭跟踪功能。
- 如果没有足够的光线信息,并且在黑暗环境中不起作用,则跟踪将无法正常工作。
- 对于渲染,您可以选择SceneKit,SpriteKit,Metal或您的自定义渲染实现。
- 如果您想使用Unity结合ARKit进行开发,您可以在这里下载一个插件,有一些简单的示例,让您易于上手。https://forum.unity3d.com/threads/arkit-support-for-ios-via-unity-arkit-plugin.474385/
使用Unity和ARKit在地面上创建门洞 本教程是用Unity结合ARKit插件制作的一个门洞Demo。最后的结果你可以在这里看到 当你对准地板时,一个洞开了,你可以看看里面。在本教程中,我们只会做这个洞。洞内的世界取决于你自己设计。 对于本教程,您将需要 - Unity 5.6.1p1 +
- IOS 11 +
- Iphone 6S+
- Unity ARKit plugin:
https://forum.unity3d.com/threads/arkit-support-for-ios-via-unity-arkit-plugin.474385/ http://blog.jayway.com/wp-content/uploads/2017/08/hole_ARKit_Tutorial.zip
开始准备: 1. 创建一个新的Unity项目,并且加载UnityARKit插件; 2. 在Assets文件中打开UnityARKitScene场景,这是一个已经设定好的场景; 3. 一些东西是我们不需要的,因此,可以在Hierarchy视图中删除RandomCube和HitCube。 同时可以禁用PointCloudParticleExample和GeneratePlanes。
4. 接下来导入我们的素材,在Assets中创建一个Prefabs文件夹,并将我们的素材放入。 5. FBX文件存有模型和动画信息。将hole.fbx文件拖到Hierarchy视图的根目录下。选择Prefabs文件夹中的hole.fbx文件,将缩放因子从1改为2。
设置动画 在hole中包含了4个子物体,分别为hole_edge、hole_inside、hole_to、innerbox,他们都使用了skinned mesh renderer。Hole中还附带了一个动画。 在hole.fbx中有一个动画片段“Take 001”,接下来,我们将动画匹配到hole上。 6. 在Assets文件夹中新建一个Scenes文件夹。在该文件夹中创建一个新的动画控制器。Assets > Create > Animator controller。重命名为 Holeanimator controller. 7. 在Hierarchy视图中选择hole,其已经有了Animator组件,将刚创建的Holeanimator controller拖到Animator组件上的controller中。
8.双击Hole animatorcontroller,将打开Animator视图。将“Take 001”拖入到Animator视图中。现在动画就和模型关联在一起了。 9. 动画本身是从打开状态到关闭状态,这里我们需要反转这个动画。在Animator视图中选择“Take 001”,在旁边的inspector视图中,将Speed改为-0.6。这样就可以反转动画,使其从关闭状态到打开状态,并且动画速度会放慢。 材质 接下来,我们将为Hole修改材质。 Innerbox给予一个黑色的材质,为了看到它时模拟一个虚空的状态。hole_inside给予一个名为hole_inside的图片的纹理。hole_top要赋予一个遮挡材质,它将隐藏框内的所有东西。而hole_edge 则给一个融合环境的材质。 9. 将下载的素材 “edge.png” and“hole_inside.png”导入工程。 10. 首先,我们给Innerbox一个黑色的材质。Assets> Create > Material. 重命名这个材质为“toInnerbox_mat”。 选择这个材质,并在Albedo属性中将颜色更改为黑色,smoothness为0,并勾选Emissions,使该材质成为静态黑色。现在将材料拖到innerbox上以应用它。 11. 接下来创建一个新的材质并将其命名为“Hole_inside_mat”。 选择材质,在Albedo属性中,点击一个可以选择纹理的小圆圈。 选择hole_inside纹理。 纹理中有一个alpha通道。 为了能够呈现,您必须将渲染模式从Opaque更改Cutout.。 将材质拖到hole_inside对象上。
遮挡材质 现在我们将为hole_top创建遮挡材质,该材质将隐藏其内部所有内容。为此,我们必须创建一个自定义遮罩Shader,将遮挡后面的物体。 创建一个新的材质。将其重命名为“hole_top_mat”。然后create > shader >standard surface shader。重命名为Mask。双击Shader打开它,并在编辑器中用以下代码替换所有内容: //代码(若报错删除错误即可) Shader "Custom/Mask" {
SubShader { //In the Tags section we define different properties for the subshader. Tags { //The main geometry render in the Geometry Pass. By Changing theGeometry pass to -1 we make sure it renders first. "Queue" = "Geometry - 1" } //The ZWrite On value turns on the render to Z-buffer. It's needed forproper sorting of the rendered passes. ZWrite On
//We don’t want to render the color pass; ColorMask 0 will do the trick. ColorMask 0
Pass {} } } //代码
我们要将Mask Shader添加到hole_top_mat材质中。在inspector视图中,材质选择Shader从standard到Mask,并将Render Queue调为1999。拖动hole_top材质到hole_top上,可以看到hole_top消失了。 13.最后,我们将创建边缘材质。创建一个新的材质,将其重命名为“hole_edge_mat”。在inspector视图,将其Shader改为Mobile > Particles >Additive。并将纹理改为“hole_ege.png”
Hit Test 当我们所有动画和材质设置完成,我们将开始设置hole的坐标。这将在hit test脚本的帮助下完成。 Unity ARKit插件提供了一个例脚本。 14. 在场景视图中,将hole作为HitCubeParent的子物体。同时删除我们不需要的HitCube。 15. 我们希望将hole的坐标对齐HitCubeParent,因此在Inspector视图中,将hole坐标的x,y,z属性设置为0。 16. 选择hole为其添加一个脚本组件,在Inspector视图中选择AddComponent(添加组件):Scripts >UnityEngine.XR.ios >Unity AR Hit Test Example。 脚本具有Hit Transform属性。 从场景中拖动HitCubeParent到HitTransform属性。因此,每当按下屏幕并检测到碰撞时,它将将HitCubeParent移动到该位置。
17.现在,当检测到碰撞时,盒子会移动正确的位置,但是我们需要盒子移动到正确位置后再触发动画。为此,我们必须修改Unity AR Hit Test Example脚本。 18. 为了正确触发动画,我们需要添加对动画的引用。 添加动画变量。 //代码 private Animator animation; //代码
19. 我们将在Start方法中获取到它,由于我们已经将动画片段关联到hole物体上,可以通过getComponent获取它; //代码 void Start() { animation = GetComponent (); } //代码
20. 接下来,我们将在触摸和碰撞检测时播放动画。 在Update中,添加动画播放的方法。 将动画名称设置为我们动画片段的的名称“Take 001”,图层为0,帧为0f,将从帧0开始动画。 //代码 animation.Play ("Take 001", 0,0.0f); //代码
就像这样: //代码 void Update () { if(Input.touchCount > 0 && m_HitTransform != null) { vartouch = Input.GetTouch(0); if(touch.phase == TouchPhase.Began) { varscreenPosition = Camera.main.ScreenToViewportPoint(touch.position); ARPointpoint = new ARPoint { x= screenPosition.x, y= screenPosition.y };
//prioritize reults types ARHitTestResultType[]resultTypes = { ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, //if you want to use infinite planes use this: //ARHitTestResultType.ARHitTestResultTypeExistingPlane, ARHitTestResultType.ARHitTestResultTypeHorizontalPlane, ARHitTestResultType.ARHitTestResultTypeFeaturePoint };
foreach(ARHitTestResultType resultType in resultTypes) { if(HitTestWithResultType (point, resultType)) { animation.Play("Take 001", 0, 0.0f); return; } } } } } //代码
制作盒子内部 门内的世界现在是空的。制作内部世界不是本教程的一部分。但是,Unity资源商店中有很多免费资源,您可以下载并放入洞内。我使用了拥有行星的天空盒,粒子和Vast Outer Space插件。现在我们要把一些球体放在Box中。 Vast Outer Space插件 https://www.assetstore.unity3d.com/cn/#!/content/38913 21. 创建一个空的游戏对象。 GameObject> Create Empty,并将它放在hole下面。 将其重命名为“inner_world”。 在里面我们将创建一些球体。创建2个球体,缩放它们并移动它们,以保证它们在盒子中。
导出到Xcode 现在我们一切准备就绪,让我们发布体验我们的app 22. Go to file > build settings 选择 IOSplatform 然后点击 Switch platform.
23. 选择Player Settings,修改Bundle Identifier和camera UsageDescription。 24. 构建应用程序。 Unity将创建一个XCode项目。 在xcode中打开项目,选择您的签名证书,并在手机上运行应用程序。
完成! 按屏幕上的某处,您将看到打开的洞。平面检测可能需要一些时间,请耐心等待。
【转载】原帖地址:
ARKit技术交流qq群:482631386 ARVR训练营:www.arvrthink.com
|