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

如何将SCNScene正确加载到ARView场景中

问题根因

ARView是RealityKit框架的渲染组件,它的scene属性是RealityKit独有的Scene类型,和SceneKit体系下的SCNScene完全不兼容,直接赋值必然失败。
另外你直接替换整个view.scene的逻辑本身就有问题:全量替换场景会清空当前AR会话已经检测到的平面、已添加的锚点,甚至你初始化的FocusEntity实例也会被清除,完全不符合往现有AR场景里放置物体的需求。

正确实现方案

你不需要替换整个AR场景,只需要把.scn格式的模型转换成RealityKit可识别的Entity实例,挂载到对应位置的锚点上,再把锚点添加到现有场景即可,具体步骤如下:

  • 从.scn资源中读取目标SCNNode
  • 将SCNNode转换为RealityKit支持的实体对象
  • 以FocusEntity当前命中平面的世界坐标创建锚点,把转换后的模型实体挂载到锚点
  • 将锚点添加到ARView现有场景中

修正后的放置逻辑代码如下:

import SwiftUI
import RealityKit
import SceneKit
import ARKit

class ARCoordinator: NSObject, ARSessionDelegate {
    weak var view: ARView?
    var focusEntity: FocusEntity?

    func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
        guard let view = self.view else { return }
        debugPrint("Anchors added to the scene: ", anchors)
        // 避免重复初始化FocusEntity
        guard self.focusEntity == nil else { return }
        self.focusEntity = FocusEntity(on: view, style: .classic(color: .yellow))
    }
    
    
    @objc func handleTap() {
        guard let view = self.view, 
              let focusEntity = self.focusEntity,
              // 确保焦点实体已经在检测到的平面上,避免放置到空位置
              focusEntity.isOnPlane else { return }
        
        // 读取scn资源和目标节点
        guard let scnScene = SCNScene(named: "art.scnassets/object.scn"),
              let scnNode = scnScene.rootNode.childNodes.first else {
            print("模型资源读取失败")
            return
        }
        
        do {
            // iOS15+ 系统提供SCNNode直接转RealityKit Entity的API
            let modelEntity = try Entity(scnNode: scnNode)
            // 根据模型实际尺寸调整缩放比例,避免模型过大/过小
            modelEntity.scale = [0.05, 0.05, 0.05]
            
            // 创建和焦点位置对齐的世界锚点
            let placementAnchor = AnchorEntity(world: focusEntity.position)
            placementAnchor.addChild(modelEntity)
            
            // 将锚点添加到现有场景,不要全量替换scene
            view.scene.addAnchor(placementAnchor)
        } catch {
            print("SCN节点转换失败:\(error.localizedDescription)")
        }
    }
}
补充说明
  • 如果你的App部署目标低于iOS15,无法使用系统自带的SCNNode转Entity能力,最稳妥的方案是直接把模型转成USDZ格式:你可以把.scn文件中的模型导出为.dae格式,拖入Xcode的资源目录,Xcode会自动完成格式转换生成可用的USDZ资源,之后直接调用try? Entity.load(named: "object")即可加载,不需要依赖第三方转换工具。
  • 不要随意修改ARView的scene属性,ARView初始化时会自动创建适配AR会话的场景实例,自定义场景会破坏世界追踪、平面检测的基础能力。

内容的提问来源于stack exchange,提问作者Mc.Lover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:39:38