You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:38:33