如何在SwiftUI上异步加载Reality Composer场景?

huangapple go评论103阅读模式
英文:

How to load Reality Composer scenes asynchronously on SwiftUI?

问题

在我的项目中,我像这样同步加载现实文件:

struct DemoView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var Scene1 = try! Experience1.loadScene1()

    var body: some View {
       ZStack {
         ARViewContainer(arView: $arView, Scene1: $Scene1)
           .ignoresSafeArea()
         Button("play") {
           Scene1.notifications.replay.post()
         }
       }
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var arView: ARView
    @Binding var Scene1: Experience1.Scene1

    func makeUIView(context: Context) -> ARView {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            arView.scene.anchors.append(Scene1)
        }
     
        return ARView
    }
}

由于我的现实场景中的模型具有大量多边形,我可以尝试以异步方式加载现实文件吗?

英文:

On my project, I load reality files synchronously like this:

struct: DemoView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var Scene1 = try! Experience1.loadScene1()

    var body: some View {
       ZStack {
         ARViewContainer(arView: $arView, Scene1: $Scene1)
           .ignoresSafeArea()
         Button("play") {
           Scene1.notifications.replay.post()
         }
       }
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var arView: ARView
    @Binding var Scene1: Experience1.Scene1

    func makeUIView(context: Context) -> ARView {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            arView.scene.anchors.append(Scene1)
        }
     
        return ARView
    }
}

Since my model in Reality Scene has a lot of polygons, can I turn to load reality files asynchronously?

答案1

得分: 2

以下是代码的中文翻译部分:

用于异步加载 Reality Composer 文件的方法

当您需要异步加载 Reality Composer 场景时,请尝试以下代码:

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

struct ARViewContainer : UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()
    
    func makeUIView(context: Context) -> ARView {
        
        Experience.loadBoxAsync(completion: { result in
            do {
                let heavyBoxScene = try result.get()
                arView.scene.anchors.append(heavyBoxScene)
            } catch {
                print("错误: \(error.localizedDescription)")
            }
        })
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

用于异步加载 USDZ 文件的方法

当您需要异步加载 .usdz 模型时,请尝试以下代码:

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer : UIViewRepresentable {
    
    @State var cancellable: AnyCancellable? = nil
    let anchor = AnchorEntity()
    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {

        DispatchQueue.main.async {

            cancellable = Entity.loadModelAsync(named: "character.usdz").sink(
                
                receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print("由于 \(error) 无法加载模型")
                    }
                    self.cancellable?.cancel()
                    
                }, receiveValue: { [self] (model: Entity) in
                    anchor.addChild(model)
                    anchor.position.z = -1.0
                    arView.scene.anchors.append(anchor)
                })
        }
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

附言

回答您的下一个问题

英文:

Async loading method for Reality Composer files

Try the following code when you need to load a Reality Composer scene asynchronously:

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

struct ARViewContainer : UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()
    
    func makeUIView(context: Context) -> ARView {
        
        Experience.loadBoxAsync(completion: { result in
            do {
                let heavyBoxScene = try result.get()
                arView.scene.anchors.append(heavyBoxScene)
            } catch {
                print("Error: \(error.localizedDescription)")
            }
        })
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

Async loading method for USDZ files

Try the following code when you need to load .usdz model asynchronously:

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer : UIViewRepresentable {
    
    @State var cancellable: AnyCancellable? = nil
    let anchor = AnchorEntity()
    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {

        DispatchQueue.main.async {

            cancellable = Entity.loadModelAsync(named: "character.usdz").sink(
                
                receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print("Unable to load a model due to \(error)")
                    }
                    self.cancellable?.cancel()
                    
                }, receiveValue: { [self] (model: Entity) in
                    anchor.addChild(model)
                    anchor.position.z = -1.0
                    arView.scene.anchors.append(anchor)
                })
        }
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

P. S.

Answer to your next question.

huangapple
  • 本文由 发表于 2023年3月8日 18:18:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671780.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定