【问题标题】:How to add multiple SCNScenes to one SCNScene?如何将多个 SCNScene 添加到一个 SCNScene?
【发布时间】:2021-04-23 05:25:45
【问题描述】:

我正在尝试创建一个允许放置 3d 对象的应用程序。我能够编写一些有效的代码,但仅限于几何对象。我需要在一个场景中添加多个 SCNScene。我该如何实现?

我是如何尝试的:

let sceneView = SCNView()
sceneView.scene = SCNScene()
sceneView.allowsCameraControl = true
sceneView.autoenablesDefaultLighting = true
sceneView.backgroundColor = .gray
    
let firstScene = SCNScene(named: "Earth.usdz")!
let firstSceneNode = firstScene.rootNode.childNode(withName: "Earth", recursively: true)!
firstSceneNode.rotate(by: .init(0, 0, 0, 0), aroundTarget: SCNVector3(0, -30, 10))
sceneView.scene?.rootNode.addChildNode(firstSceneNode)
    
let secondScene = SCNScene(named: "Venus.usdz")!
let secondSceneNode = secondScene.rootNode.childNode(withName: "Venus", recursively: true)!
sceneView.scene?.rootNode.addChildNode(secondSceneNode)

当我删除 secondScene 时,一切都适用于一个模型。

谢谢!

【问题讨论】:

    标签: swift swiftui scenekit


    【解决方案1】:

    在 SceneKit 中,每个 SCNScene 可以包含多个连接到场景的root 节点的 SCNNode。正如您在图像上看到的,这些节点不仅可以是几何体,还可以是灯具、相机或粒子系统。

    您可以轻松地从任何 SCNScene 树中检索具有相应材质的任何所需 SCNNode 并粘贴到其他场景(在本例中为空场景)。

    import SwiftUI
    import SceneKit
    
    struct ContentView: View {
        
        var body: some View {
            SceneKitView().ignoresSafeArea()
        }
    }
    
    struct SceneKitView: UIViewRepresentable {
        
        let sceneView = SCNView(frame: .zero)
    
        func makeUIView(context: Context) -> SCNView {
            
            sceneView.allowsCameraControl = true
            sceneView.autoenablesDefaultLighting = true
            sceneView.backgroundColor = .black
            sceneView.scene = SCNScene()
            
            let scene01 = SCNScene(named: "Earth.usdz")!
            let scene02 = SCNScene(named: "Mars.usdz")!
            let scene03 = SCNScene(named: "Sun.usdz")!
    
            let earthNode = scene01.rootNode.childNode(withName: "earthPlanet", 
                                                    recursively: true)!
            earthNode.position.x = -1.0
    
            let marsNode = scene02.rootNode.childNode(withName: "marsPlanet", 
                                                   recursively: true)!
            marsNode.position.x = 0.2
    
            let sunNode = scene03.rootNode.childNode(withName: "sunStar", 
                                                  recursively: true)!
            sunNode.position.x = 1.5
            
            sceneView.scene?.rootNode.addChildNode(earthNode)
            sceneView.scene?.rootNode.addChildNode(marsNode)
            sceneView.scene?.rootNode.addChildNode(sunNode)
            return sceneView
        }
        func updateUIView(_ uiView: SCNView, context: Context) { }
    }
    

    附言

    但您不能将多个 SCNScenes 加载到单个 SCNScenes 中

    【讨论】:

    • 我试过这个方法,但不幸的是我得到:致命错误:在展开可选值时意外发现 nil
    • 如果场景中的节点名称错误,则会出现错误。 Scene graph 中的节点名称可能与usdz 文件的名称不同。
    • 节点名称(如果正确)。预览中场景显示正确,但模拟器中应用崩溃
    • 谢谢,我正在等待
    • 成功了,看来问题还是出在模型上,谢谢!
    【解决方案2】:

    只需从每个子场景中取出您想要的节点(在这种情况下,您似乎想要每个行星场景中的根节点)并将 add 它们分别作为您要呈现的场景中的子节点(即太阳系场景)。

    【讨论】:

    • 扩展 SCNNode { 便利初始化(命名名称:字符串){ self.init() 守卫让场景 = SCNScene(命名:名称) else { return } for childNode in scene.rootNode.childNodes { addChildNode(子节点)}}}。对吗?
    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 2017-11-27
    • 2021-03-25
    • 2022-12-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    相关资源
    最近更新 更多