我正在使用 GameplayKit 的 GKObstacleGraph 为我的 iOS 10.2 SpriteKit 游戏添加寻路支持。该游戏是一个自上而下的 2D 游戏,它具有我的“士兵”无法通过的不可逾越的障碍。
为我的游戏关卡创建一个包含大约 500 个障碍物的 GKObstacleGraph 大约需要 50 秒。这对我的用户来说太长了等待。
由于游戏地图布局在加载后永远不会动态变化,我决定创建一次图形:
let graph = GKObstacleGraph(obstacles: obstacles, bufferRadius: 5, nodeClass: GKGraphNode2D.self)
归档到文件:
let directories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if let documents = directories.first {
if let filePath = String(documents + "/obstacle.graph") {
NSKeyedArchiver.archiveRootObject(graph, toFile: filePath)
}
}
将文件从设备复制到我的笔记本电脑并将文件添加到我的包中。然后,当我加载我的游戏关卡时,我只是解压缩图形对象:
if let filePath = Bundle.main.path(forResource: "obstacle", ofType: "graph") {
let graph = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as! GKObstacleGraph<GKGraphNode2D>
return graph
}
从理论上讲,这应该快得多,因为我不必计算图形,只需从文件中读取它(取消归档)。
但是,根据障碍物的数量及其相对位置,会发生以下三种情况之一:
- NSKeyedArchiver.archiveRootObject 崩溃。
- 存档工作,但 NSKeyedUnarchiver.unarchiveObject 崩溃。
- 存档和取消存档都有效,但我无法使用 GKObstacleGraph.findPath 找到绕过障碍物的路径
如果我跳过(取消)归档步骤,我可以完成所有这些工作:
此外,在模拟器 (iPhone 7) 上, (un)archive永远不会崩溃,但之后寻路总是失败。
这里发生了什么?我已将其作为错误报告给 Apple,但我仍然希望我错过了一些东西。
我尝试了替代解决方案来解决我使用自己的格式写入/读取节点和文件障碍的问题。但是 GKObstacleGraph 的障碍属性是get only,这让我有了构造函数,然后我又回到等待 50 秒。
我创建了一个公共测试项目 git repo:
https://bitbucket.org/oixx/gkobstaclegraphcrashproof.git
它显示了在设备上运行时失败的三种不同场景。为简单起见,它将文件读/写到设备,而不是捆绑。