如何在visionOS的SwiftUI 2D窗口中显示RealityKit透视相机视图?
如何在visionOS的SwiftUI 2D窗口中显示RealityKit透视相机视图?
嘿,我来帮你搞定这个问题!你做的是纯虚拟的visionOS沉浸式应用,想把RealityKit里自定义的透视相机画面显示在SwiftUI的2D窗口里,这个需求完全可以实现,我给你说个简单靠谱的方法:
核心思路
咱们可以利用ARView来渲染虚拟相机的画面——别担心,虽然它名字带AR,但咱们可以禁用AR会话,把它当成纯RealityKit的渲染容器,然后指定它的视角为你自定义的PerspectiveCamera实体就行。
具体实现步骤
封装ARView为SwiftUI组件
先写一个UIViewRepresentable的结构体,把ARView包装成SwiftUI能识别的视图,同时配置它为非AR模式:import SwiftUI import RealityKit import ARKit struct CameraPreviewView: UIViewRepresentable { let cameraEntity: PerspectiveCamera let sceneContent: Entity func makeUIView(context: Context) -> ARView { let arView = ARView(frame: .zero) // 禁用AR会话,不需要真实世界追踪 arView.session.pause() arView.environment.sceneUnderstanding.options = [] // 把你的虚拟场景内容添加到ARView的场景中 arView.scene.addAnchor(sceneContent) // 设置ARView的视角为咱们自定义的相机 arView.cameraMode = .nonAR arView.pointOfView = cameraEntity return arView } func updateUIView(_ uiView: ARView, context: Context) { // 如果相机的属性(比如位置、FOV)有动态变化,在这里更新视角 uiView.pointOfView = cameraEntity } }在SwiftUI窗口中使用这个组件
接下来在你的主视图里,创建好实体和相机,然后把封装好的CameraPreviewView放到2D窗口中:struct ContentView: View { // 初始化你的实体和自定义相机 let sceneRootEntity = Entity() let customCamera: PerspectiveCamera = { let camera = PerspectiveCamera() camera.camera.far = 10000 camera.camera.fieldOfViewInDegrees = 60 camera.camera.near = 0.01 // 可以给相机设置初始位置,比如让它对着场景内容 camera.position = [0, 0, 3] return camera }() init() { // 把相机添加到根实体 sceneRootEntity.addChild(customCamera) // 这里添加你的ModelEntity内容,比如放个测试用的立方体 let testModel = ModelEntity(mesh: .generateBox(size: 1)) testModel.position = [0, 0, -2] sceneRootEntity.addChild(testModel) } var body: some View { WindowGroup { VStack(spacing: 20) { Text("虚拟相机实时画面") .font(.title) // 把相机预览视图放到窗口里 CameraPreviewView(cameraEntity: customCamera, sceneContent: sceneRootEntity) .frame(height: 400) .cornerRadius(12) .shadow(radius: 5) } .padding() } } }
为什么这么做?
ARView本身就是RealityKit的渲染载体,咱们禁用AR会话后,它就只会渲染你提供的虚拟场景,完全符合你的非AR应用需求。- 通过设置
pointOfView为自定义相机,ARView就会从这个相机的视角渲染画面,直接输出你想要的相机视图。
如果你的相机位置或者参数会动态变化,记得在updateUIView方法里同步更新pointOfView,保证画面实时同步。
备注:内容来源于stack exchange,提问作者Reinhard Männer
相关产品推荐
相关产品推荐

