SceneKit(SwiftUI)中有关场景更改的初始化材料

问题描述 投票:0回答:1

我在SwiftUI应用中使用SceneKit来显示从Blender导出的.scn文件转换而来的某些.dae文件。

正在使用UIViewRepresentable显示SceneKit。

我正在显示逐步指导说明,并且每个步骤都包含一些文本和动画。每个动画都是其自己的.scn文件,我将根据当前步骤交换场景文件。

我的问题是,当场景交换时,我需要对材质进行一些初始化,但是在发生这种情况时,仅调用updateUIView,我不想在这里做这项工作,因为每次动画被调用时都会调用它。暂停等

我希望每次更换场景后都要进行一次这项工作,但是我正在努力用当前的实现方法来找到解决方案。

我认为我处理场景交换的方式不正确,但是我想知道是否有人可以将我指向正确的方向。

谢谢!

请参见下面的完整代码:

struct MaintenanceFlowDetailView: View {

    var maintenanceFlow: MaintenanceFlow
    @State private var currentStepIndex = 0
    @State private var pauseAnimation = false

    func stepBackwards() {
        currentStepIndex -= 1
        pauseAnimation = false
    }

    func stepForwards() {
        currentStepIndex += 1
        pauseAnimation = false
    }

    func togglePauseAnimation() {
        pauseAnimation = !pauseAnimation
    }

    var body: some View {
        NavigationView{
            VStack(alignment: .leading, spacing: 12){
                SceneKitView(sceneFilePath: maintenanceFlow.steps[currentStepIndex].scenePath, pauseAnimation: $pauseAnimation)
                    .frame(height: 300)
                Text(maintenanceFlow.steps[currentStepIndex].text)
                Spacer()
                HStack{
                    if currentStepIndex > 0 {
                        Button(action: stepBackwards) {
                            Text("Back")
                        }
                    }
                    Spacer()
                    Button(action: togglePauseAnimation) {
                        Text(pauseAnimation ? "Play" : "Pause")
                    }
                    Spacer()
                    if currentStepIndex < maintenanceFlow.steps.count - 1 {
                        Button(action: stepForwards) {
                            Text("Next")
                        }
                    }

                }
            }.padding()
            .navigationBarTitle(Text(maintenanceFlow.name))
        }

    }
}

struct SceneKitView : UIViewRepresentable {

    var sceneFilePath: String
    @Binding var pauseAnimation: Bool

    func makeUIView(context: Context) -> SCNView {

        print("calling CREATE view")

        // I NEED TO INITIALISE MATERIALS ETC JUST ONCE HERE...

        let scnView = SCNView()
        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        print("calling UPDATE view")

        // BUT THE SCENE IS REPLACED HERE :(

        let scene = SCNScene(named: sceneFilePath)!
        scene.isPaused = pauseAnimation
        scnView.scene = scene

        scnView.showsStatistics = true
    }
}

ios swift swiftui scenekit
1个回答
0
投票

使用以下内容:

struct SceneKitView : UIViewRepresentable {

    var sceneFilePath: String
    @Binding var pauseAnimation: Bool

    func makeUIView(context: Context) -> SCNView {

        print("calling CREATE view")

        let scnView = SCNView()
        let scene = SCNScene(named: sceneFilePath)!

        scnView.scene = scene
        scnView.showsStatistics = true
        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        print("calling UPDATE view")
        scene.isPaused = pauseAnimation
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.