SceneKit:如何在运行时从其他场景加载节点?

时间:2019-05-19 16:17:24

标签: swift scenekit

我有主场景文件:main.scn和其他几个带有附加SCNNodes的场景文件:scene1.scnscene2.scnscene3.scn,...在应用程序启动时,我加载了scene1.scn中需要的节点,并将它们添加到main.scn中(显示在屏幕上)。在运行时,我需要从其他sceneN.scn文件中添加其他节点。我尝试了两种方法,每种方法都未使用:

1)renderer(_, updateAtTime)内部,我只加载了所需的节点:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    let scene2 = SCNScene(named: "game.scnassets/scene2.scn")!
    let node = scene2.rootNode.childNode(withName: "nodeName", recursively: false)!
    mainScene.rootNode.addChildNode(node)
}

在这种情况下,我会收到错误消息: [SceneKit]错误:在另一个场景()的渲染回调中修改了场景。这是不允许的,并且可能导致崩溃

2)在后台加载Scene2和节点,将其添加到某个nodesToShow数组中,并在renderer(_, updateAtTime)内部显示该数组中的节点。在这种情况下,有时会出现错误:

com.apple.scenekit.scnview-renderer(17):EXC_BAD_ACCESS(代码= 1,地址= 0xf000000010a10c10)

也许您知道一些在运行时从其他场景文件加载和显示节点的真正解决方案?

1 个答案:

答案 0 :(得分:1)

您可以使用SCNReferenceNode从另一个场景文件中加载内容:

  

一个场景图节点,用作从单独的场景文件中加载内容的占位符。

然后,您应该将.load()命令括在SCNTransaction块中以创建原子更新:

  

此事务将您在该线程的运行循环的当前迭代期间对同一线程所做的所有其他更改分组。当下一次迭代运行循环时,SceneKit自动提交事务,将在事务中进行的所有更改自动应用于演示场景图(即当前显示的场景图的版本)。

Swift代码:

let url = Bundle.main.url(forResource: "ship", withExtension: "scn", subdirectory: "art.scnassets")!
let referenceNode = SCNReferenceNode(url: url)!
scnView.scene!.rootNode.addChildNode(referenceNode)
SCNTransaction.begin()
referenceNode.load()
SCNTransaction.commit()