【问题标题】:SceneKit: How to load nodes from additional scenes at runtime?SceneKit:如何在运行时从其他场景加载节点?
【发布时间】:2019-10-06 03:51:33
【问题描述】:

我有主场景文件: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)

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

【问题讨论】:

    标签: swift scenekit


    【解决方案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()
    

    【讨论】:

    • 如果我执行renderer(_, updateAtTime) 中的代码,我会得到错误:[SceneKit] 错误:在另一个场景的渲染回调中修改了场景 ()。这是不允许的,可能会导致崩溃
    • 没有.load()屏幕上没有节点也没有错误。
    • 我已经编辑了答案。如果您将.load() 命令放在SCNTransaction 块中,错误将消失。
    猜你喜欢
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 2015-01-04
    • 2017-12-03
    • 2017-01-11
    • 2017-12-05
    相关资源
    最近更新 更多