如何判断Entity已成功附加到AnchorEntity后执行指定函数
实现方案
你当前doSomething()触发过早的核心原因是Entity.loadAsync为异步操作,sink的两个闭包都会在加载完成后才异步执行,而你把doSomething()放在了异步流程外部,调用addModel时会同步立即执行,与加载流程完全无关。
要实现「Entity加载完成且成功附加到AnchorEntity后再执行」的需求,可按以下逻辑调整:
基础实现(满足绝大多数场景)
直接将doSomething()移入receiveValue闭包末尾,同时增加附加成功的校验:
func addModel(to planeAnchor: AnchorEntity) { Entity.loadAsync(named: "SomeUSDZModel") .sink { completion in switch completion { case .finished: print("Ok") case .failure(let error): print(error.localizedDescription) } } receiveValue: { model in // Entity should be added before the animation is started. planeAnchor.addChild(model) if let walkingAnimation = model.availableAnimations.first { model.playAnimation(walkingAnimation.repeat(duration: .infinity), transitionDuration: 1.25, blendLayerOffset: 0, separateAnimatedValue: false, startsPaused: false) } self.model = model // 新增校验逻辑:确认model已经成功附加到目标锚点 guard model.parent == planeAnchor else { return } doSomething() } .store(in: &subscriptions) }
更稳妥的实现(避免渲染帧延迟问题)
如果你的场景中存在RealityKit内部渲染帧延迟导致addChild后parent未立即更新的特殊情况,可以等待下一个渲染循环后再校验执行:
func addModel(to planeAnchor: AnchorEntity) { Entity.loadAsync(named: "SomeUSDZModel") .sink { completion in switch completion { case .finished: print("Ok") case .failure(let error): print(error.localizedDescription) } } receiveValue: { model in // Entity should be added before the animation is started. planeAnchor.addChild(model) if let walkingAnimation = model.availableAnimations.first { model.playAnimation(walkingAnimation.repeat(duration: .infinity), transitionDuration: 1.25, blendLayerOffset: 0, separateAnimatedValue: false, startsPaused: false) } self.model = model // 等待下一个渲染帧后再校验执行 Task { @MainActor in try? await Task.sleep(nanoseconds: 16_000_000) // 约等于1帧的时长 guard model.parent == planeAnchor else { return } doSomething() } } .store(in: &subscriptions) }
内容的提问来源于stack exchange,提问作者Kuba Gawecki
相关产品推荐
相关产品推荐

