1

我正在使用 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
}

从理论上讲,这应该快得多,因为我不必计算图形,只需从文件中读取它(取消归档)。

但是,根据障碍物的数量及其相对位置,会发生以下三种情况之一:

  1. NSKeyedArchiver.archiveRootObject 崩溃。
  2. 存档工作,但 NSKeyedUnarchiver.unarchiveObject 崩溃。
  3. 存档和取消存档都有效,但我无法使用 GKObstacleGraph.findPath 找到绕过障碍物的路径

如果我跳过(取消)归档步骤,我可以完成所有这些工作:

成功寻路

此外,在模拟器 (iPhone 7) 上, (un)archive永远不会崩溃,但之后寻路总是失败

这里发生了什么?我已将其作为错误报告给 Apple,但我仍然希望我错过了一些东西。

我尝试了替代解决方案来解决我使用自己的格式写入/读取节点和文件障碍的问题。但是 GKObstacleGraph 的障碍属性是get only,这让我有了构造函数,然后我又回到等待 50 秒。

我创建了一个公共测试项目 git repo:

https://bitbucket.org/oixx/gkobstaclegraphcrashproof.git

它显示了在设备上运行时失败的三种不同场景。为简单起见,它将文件读/写到设备,而不是捆绑。

4

1 回答 1

0

我对崩溃一无所知,但您列表中的#3 可能是由于connectNodeToLowestCostNode:bidirectional:未将您的士兵实际连接到图表造成的,因为节点数组在取消归档后是不可变的。

解决方案是归档节点而不是图形,然后只需从节点创建图形

NSArray *nodes  = [NSKeyedUnarchiver unarchiveObjectWithData:self.nodesArray];
GKGraph *graph  = [[GKGraph alloc] initWithNodes:nodes];
于 2019-05-16T14:58:32.863 回答