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

Ser*_* Di 4 scenekit swift

我有主场景文件:main.scn以及其他几个带有附加 SCNNode 的场景文件: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)
}
Run Code Online (Sandbox Code Playgroud)

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

2)在后台加载场景2和节点,添加一些nodesToShow数组并在里面renderer(_, updateAtTime)显示数组中的节点。在这种情况下有时我会得到错误:

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

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

Mas*_*nis 7

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

\n\n
\n

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

\n
\n\n

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

\n\n
\n

此事务对您在该线程\xe2\x80\x99s 运行循环的当前迭代期间从同一线程所做的任何其他更改进行分组。当运行循环下次迭代时,SceneKit 自动提交事务,以原子方式将事务期间所做的所有更改应用到演示场景图(即当前正在显示的场景图的版本)。

\n
\n\n

斯威夫特代码:

\n\n
let url = Bundle.main.url(forResource: "ship", withExtension: "scn", subdirectory: "art.scnassets")!\nlet referenceNode = SCNReferenceNode(url: url)!\nscnView.scene!.rootNode.addChildNode(referenceNode)\nSCNTransaction.begin()\nreferenceNode.load()\nSCNTransaction.commit()\n
Run Code Online (Sandbox Code Playgroud)\n