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

iOS AR开发:如何获取自定义USD场景的父ModelEntity?

解决自定义USD模型导入后无法获取ModelEntity的问题

问题分析

使用Xcode标准Box场景时,可通过指定名称simpBld_root找到ModelEntity,但导入自定义USD模型后,直接用控制台显示的“USD scene”查找失败,核心原因是自定义USD的实体层级与标准Box不同,且“USD scene”并非实体的真实name属性值。

解决方案

1. 排查实体层级与真实名称

加载自定义USD锚点后,枚举并打印所有实体的名称和类型,明确目标实体的真实名称:

usdAnchor.enumerateEntities { entity, stop in
    print("实体名称:\(entity.name),类型:\(type(of: entity))")
}

运行代码后查看控制台输出,即可找到自定义USD根实体的真实名称(而非控制台显示的“USD scene”)。

2. 两种方式获取目标ModelEntity

方式一:直接获取锚点的第一个子实体

自定义USD导入后,锚点的第一个子实体通常就是模型的根节点,可直接获取:

if let usdRoot = usdAnchor.children.first as? GstReady {
    // 递归生成碰撞体(适配USD模型的多层级结构)
    usdRoot.generateCollisionShapes(recursive: true)
    // 安装交互手势
    arView.installGestures([.rotation, .scale, .translation], for: usdRoot)
}

方式二:通过真实名称查找

根据步骤1打印出的真实名称,使用findEntity(named:)精准查找:

if let usdRoot = usdAnchor.findEntity(named: "你的USD根实体真实名称") as? GstReady {
    usdRoot.generateCollisionShapes(recursive: true)
    arView.installGestures([.rotation, .scale, .translation], for: usdRoot)
}

修改后的完整代码示例

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        ARViewContainer().edgesIgnoringSafeArea(.all)
    }
}

struct ARViewContainer: UIViewRepresentable {
    
    func makeUIView(context: Context) -> ARView {
        
        let arView = ARView(frame: .zero)
        typealias GstReady = Entity & HasCollision
        
        // 替换为你自定义USD对应的load方法(导入后RealityKit自动生成)
        let usdAnchor = try! Experience2.loadCustomUSD()
        
        arView.scene.anchors.append(usdAnchor)
        
        // 打印所有实体,排查层级与名称
        usdAnchor.enumerateEntities { entity, stop in
            print("实体名称:\(entity.name),类型:\(type(of: entity))")
        }
        
        // 方式一:获取第一个子实体
        if let usdRoot = usdAnchor.children.first as? GstReady {
            usdRoot.generateCollisionShapes(recursive: true)
            arView.installGestures([.rotation, .scale, .translation], for: usdRoot)
        }
        
        // 方式二:根据真实名称查找(注释方式一,打开此注释即可)
        // if let usdRoot = usdAnchor.findEntity(named: "USD根实体真实名称") as? GstReady {
        //     usdRoot.generateCollisionShapes(recursive: true)
        //     arView.installGestures([.rotation, .scale, .translation], for: usdRoot)
        // }
        
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {}
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

注意事项

  • 确保自定义USD已正确导入到RealityKit项目中,生成对应的loadXXX()方法(可在Experience2.swift中查看)。
  • 使用generateCollisionShapes(recursive: true):若USD模型包含多层级子实体,递归生成碰撞体才能让手势作用于整个模型。
  • 不要依赖控制台显示的“USD scene”作为查找名称,必须通过枚举实体获取真实的name属性值。

内容的提问来源于stack exchange,提问作者Remy Konings

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:25:18