本文是有关 ARTris 的一系列文章的第2部分 。 使用ARKit,Node.js和Firebase构建的多人实时3D AR Tetris游戏。 如果您是本系列的新手,我们建议您从 介绍 开始 。 分叉 iOS客户端和游戏引擎存储库以开始实验。
今天,我们要讨论如何减少玩家与屏幕的互动次数,以及如何在不中断AR体验的情况下在两个视图控制器之间进行转换。

减少手势
在第一个实现中,我们使用了三个手势。 平移,收缩和旋转以对齐玩家的游戏坐标系。 我们使用全景手势在环境中移动网格,使用捏手势进行缩放,并使用旋转手势将其绕y轴旋转。 使用三个手势的效果不如我们希望的那样。 苹果在他们的文档中谈到了这个陷阱。
对于相对于现实世界而言尺寸有限的物体(例如家具),如果将物品放置在正确的尺寸上,则缩放比例是无关紧要的。 缩放不是调整对象距离的补救方法,例如,使对象变大以使其看起来更近,只会导致距离更远的更大对象。
…
例如,两指捏合手势与两指旋转手势非常相似。 如果您执行两个类似的手势,请确保测试您的应用并确保正确解释了它们。
我们遇到了Apple文档描述的相同问题。 使用两个两个手指的手势变得太含糊,虚拟网格对它们的响应不佳。 另外,由于玩家过多触摸屏幕,AR浸没了。 因此,我们决定将三个触摸事件按比例缩放到单个旋转手势,以最大程度地减少用户与屏幕互动的次数。
在两个视图控制器之间过渡
我们面临的第二个障碍是如何从本地化过渡到游戏环境。 我们提出了两种解决方案-使用segue或将子视图控制器添加到主视图控制器。
使用segue
我们尝试使用segue在两个视图控制器之间转换。 第一个视图控制器使用旋转手势视图处理网格的本地化,第二个视图控制器处理游戏引擎和用户与Tetris网格的交互。
首先,在筛选之前,我们暂停AR会话并将该会话传递给新的视图控制器。 其次,我们传递shadowBinder,它是网格所连接的节点。 我们这样做是为了保持指向放置网格位置的指针。
第三,转换完成后,在新的视图控制器中,我们使用与以前相同的配置恢复会话。
这种过渡有两个问题。 首先,暂停AR会话会中断它,并且不能保证它会像以前一样完全恢复。 其次,在过渡过程中,屏幕会变白约三秒钟。 我们的下一个尝试是使用效果更好的子视图控制器。
使用子视图控制器
子视图控制器本质上是一个容器视图控制器,但是由其自己的视图控制器类管理。 这使我们有机会在确保AR会话不中断的同时保持代码模块化。
在添加子视图控制器之前,当前视图控制器的ARSession委托设置为nil。 这是为了停止调用其didUpdatFrame
函数,该函数随每个渲染的帧更新网格的位置。 这样可以固定网格的位置,以便用户可以开始玩游戏。
接下来,调用updateView
函数。 此功能将新的视图控制器添加为子视图控制器。 添加子视图控制器分三个步骤完成:将子视图控制器添加到其父视图,将其视图作为子视图添加到其父视图,并更新其视图边界。
最后,我们需要学习如何实例化子视图控制器。 我们在惰性声明中执行此操作,并在初始化闭包中添加要从其父级传递给它的所有引用。
现在,我们完成了! 我们已经成功地管理了到新视图控制器类的过渡,而没有中断AR会话。
下一个
明天我们将讨论触摸事件到渲染新帧之前发生的步骤。
从触摸事件到新框架
参考资料和进一步阅读
适用于iOS的View Controller编程指南
容器视图控制器
使用容器视图控制器管理视图控制器