RealityKit无法获取相机位置,加载cube.usdz模型至相机位置失败求助
问题原因与解决方案
为什么会进入why does nothing work分支?
你调用load3DModel()的时机太早了——在viewDidLoad里刚启动ARSession就立刻获取currentFrame,此时ARSession还没完成初始化、还没捕获到第一帧画面,所以arView.session.currentFrame是nil,自然会进入else分支。
正确的实现步骤
- 不要在
viewDidLoad里直接加载模型,而是通过ARSession的代理方法,等到ARSession成功捕获到第一帧后再处理。 - 模型添加到场景的方式有误,
Entity.load返回的是普通Entity,不能直接强转为HasAnchoring,需要给模型添加一个AnchorEntity。
修改后的完整代码
import UIKit import RealityKit import ARKit class Load3DModelViewController: UIViewController, ARSessionDelegate { @IBOutlet weak var arView: ARView! override func viewDidLoad() { super.viewDidLoad() // 设置AR配置 let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = .horizontal arView.session.delegate = self // 先设置代理再启动session arView.session.run(configuration) } // ARSession成功更新帧时调用 func session(_ session: ARSession, didUpdate frame: ARFrame) { // 只加载一次模型,避免重复添加 guard arView.scene.anchors.first(where: { $0.name == "CubeAnchor" }) == nil else { return } load3DModel(with: frame.camera.transform) } func load3DModel(with cameraTransform: simd_float4x4) { let modelFileName = "cube.usdz" guard let modelEntity = try? Entity.load(named: modelFileName) else { print("Failed to load the 3D model") return } // 计算模型位置:在相机前方1米处 let cameraPosition = cameraTransform.columns.3 let modelPosition = SIMD3<Float>(cameraPosition.x, cameraPosition.y, cameraPosition.z - 1) // 创建锚点实体,将模型添加到锚点上 let anchorEntity = AnchorEntity(world: modelPosition) anchorEntity.name = "CubeAnchor" // 标记锚点,避免重复加载 anchorEntity.addChild(modelEntity) arView.scene.addAnchor(anchorEntity) } }
关键修改点说明
- 代理设置时机:先设置
arView.session.delegate = self,再启动session,确保能接收到帧更新事件。 - 延迟加载模型:通过
session(_:didUpdate:)代理方法,等到ARSession有了有效帧后再获取相机位置加载模型。 - 正确添加锚点:使用
AnchorEntity作为模型的锚点,而不是直接将普通Entity强转为HasAnchoring,这是RealityKit中添加实体到场景的标准方式。 - 避免重复加载:通过给锚点设置唯一名称,检查场景中是否已有该锚点,防止每次帧更新都重复添加模型。
内容的提问来源于stack exchange,提问作者Tario You
相关产品推荐
相关产品推荐

