iOS 18中使用RealityView实现同步立体VR视图的问题
iOS 18中使用RealityView实现同步立体VR视图的问题
我懂你现在的困扰啦——左右两个RealityView里的白盒子,左边转得欢,右边却完全不动,根本没法形成立体VR该有的同步效果对吧?
问题根源
你代码里第二个RealityView用了box.clone(recursive: true),克隆出来的是一个完全独立的实体副本,和原box没有任何绑定关系。所以当你在rotateMe()里修改原box的旋转时,克隆体根本接收不到任何更新,自然就一动不动了。
解决方案:用共享状态同步两个视图
我们可以用SwiftUI的可观察对象(ObservableObject)来管理共享的旋转状态,让两个RealityView都监听这个状态的变化,从而同步更新各自的3D实体。下面是修改后的完整代码:
import SwiftUI import RealityKit // 管理共享旋转状态的类 class RotationManager: ObservableObject { @Published var rotation: simd_quatf = simd_quatf(angle: .pi / 4, axis: [0,1,1]) } struct ContentView: View { // 创建共享的旋转管理器实例 @StateObject private var rotationManager = RotationManager() @State private var rotateTimer: Timer? var body: some View { HStack(spacing: 0) { // 左侧VR视图 RealityView { content in // 创建左侧的盒子实体 let boxMesh = MeshResource.generateBox(size: 0.5) let whiteMaterial = SimpleMaterial(color: .white, isMetallic: false) let boxEntity = ModelEntity(mesh: boxMesh, materials: [whiteMaterial]) let anchor = AnchorEntity() anchor.addChild(boxEntity) // 初始应用共享的旋转状态 anchor.transform.rotation = rotationManager.rotation content.add(anchor) // 订阅旋转状态变化,同步更新左侧实体 rotationManager.$rotation .sink { newRotation in anchor.transform.rotation = newRotation } .store(in: &content.subscriptions) } // 右侧VR视图 RealityView { content in // 创建右侧的盒子实体(和左侧完全相同) let boxMesh = MeshResource.generateBox(size: 0.5) let whiteMaterial = SimpleMaterial(color: .white, isMetallic: false) let boxEntity = ModelEntity(mesh: boxMesh, materials: [whiteMaterial]) let anchor = AnchorEntity() anchor.addChild(boxEntity) // 初始应用共享的旋转状态 anchor.transform.rotation = rotationManager.rotation content.add(anchor) // 订阅旋转状态变化,同步更新右侧实体 rotationManager.$rotation .sink { newRotation in anchor.transform.rotation = newRotation } .store(in: &content.subscriptions) } } .background(.black) .onAppear { // 5秒后启动旋转动画 DispatchQueue.main.asyncAfter(deadline: .now() + 5) { // 先清空可能存在的旧定时器 rotateTimer?.invalidate() // 启动定时旋转 rotateTimer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { _ in updateRotation() } } } } // 更新共享旋转状态的方法 private func updateRotation() { // 计算当前旋转角度,每次增加0.01弧度 let currentAngle = rotationManager.rotation.angle let newAngle = currentAngle + 0.01 // 应用新的旋转到共享状态 rotationManager.rotation = simd_quatf(angle: newAngle, axis: [0,1,0]) } }
关键修改点说明
- 共享状态管理:新增
RotationManager类,用@Published标记旋转属性,确保状态变化时能通知所有订阅者。 - 双视图订阅状态:每个RealityView都创建自己的实体实例(不能共用同一个实体,因为每个RealityView有独立的场景),然后订阅
rotationManager.rotation的变化,同步更新自身实体的旋转。 - 旋转逻辑迁移:把原来直接修改
box的代码,改成修改共享的rotation属性,这样两个视图会自动同步更新。
这样修改后,左右两个盒子就会完全同步旋转,完美实现你想要的立体VR同步效果啦!
备注:内容来源于stack exchange,提问作者Ostoura
相关产品推荐
相关产品推荐

