我正试图从一个Reality Composer项目中的一个场景中加载一个Entity到我的代码中.

我直接接触到自动生成的.reality文件,因为我不希望它自动放置在它检测到的第一个平面上.我遵循了文章Taking Control of Scene Anchoring中的文档.

样本项目的名称是Experience,在那里我有2个场景.

  1. 自动生成的框,它自动随新创建的项目一起提供.
  2. 一个六边形的导入USDZ文件.

我用来加载两者作为ModelEntity的代码如下:

let url = Bundle.main.url(forResource: "Experience", 
                        withExtension: "reality")!
            .appending(path: "SceneName", directoryHint: .notDirectory)
        
let modelEntity = try! Entity.loadModel(contentsOf: url)

其中SceneName要么是Box,要么是Hexagon.

两个都无法加载.

如果我改用以下代码,它们会成功,但它们被加载为Entity,而不是ModelEntity:

let modelEntity = try! Entity.load(contentsOf: url)

是否可以将对象加载为ModelEntity而不是Entity?到目前为止,我在这post中找到的方法是遍历子层次,找到第一个ModelEntity,并将其模型和物理复制到其父对象上(在我的例子中,这是可行的,因为我在场景中只有一个对象).


Edit:即使我命名场景中的对象,然后try 使用在场景中找到的"根"Entity对象上的findEntity(named:)方法获取它们,我也会再次得到Entity,而不是ModelEntity.

推荐答案

Reality Composer's .rcproject

如果您使用的是Reality Composer的Experience.rcproject文件,请try 以下技巧.实现findEntity(named:)方法,然后使用类型转换as!操作符从RC场景中获取所需的模型实体.

import UIKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    typealias ModelPack = ModelEntity & HasPhysicsBody
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let scene1 = try! Experience.loadBox()
        let scene2 = try! Experience.loadHexagon()
        
        print(scene1); print(scene2)
        
        let boxModel = scene1.findEntity(named: "simpBld_root") as! ModelPack
        let hexModel = scene2.findEntity(named: "simpBld_root") as! ModelPack
        boxModel.position.x = -0.075
        hexModel.position.x = 0.075
        
        let anchor = AnchorEntity()     // any RealityKit or ARKit anchor
        anchor.scale *= 3
        anchor.addChild(boxModel)
        anchor.addChild(hexModel)
        
        arView.scene.anchors.append(anchor)
    }
}

.reality file

苹果专有的.reality格式提供了更快的上传时间.使用以下方法将.reality个文件加载到您的3D场景中.记住,每个RealityKit的场景都是实体的层次 struct .

import UIKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    typealias ModelPack = ModelEntity & HasPhysicsBody
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let scene = try! Entity.load(named: "SomeScene.reality")
        print(scene)
        
        let boxModel = scene.findEntity(named: "simpBld_root") as! ModelPack
        
        let anchor = AnchorEntity()
        anchor.addChild(boxModel)
        arView.scene.anchors.append(anchor)
    }
}

Swift相关问答推荐

是否有一个Kotlin等价的Swift s @ AddendableReport注释'

编写Swift字符串的属性包装时遇到问题

按数组大小进行类型判断?

如何根据 DatePicker 中选定的日期实现 TabView 页面切换?

允许视图在视图内更改

为什么变量不存储在 Swift 的过程数据区中

在Swift中如何用变量计算0.9的立方

当变量首次用于其自己的初始化时,如何清除变量...在初始化之前使用错误?

如何将视图添加到多行文本视图的末尾?

在 Swift 中为(递归)扩展提供默认实例参数

如何有条件地依赖桌面与 iOS 的系统库?

单击按钮后的计时器发布者初始化计时器

在 Select 器上显示alert Select SwiftUI

任何使 ScrollView 像 List 一样执行更灵活的修饰符?

如何以快速 Select 器菜单样式调整图像大小

Swift中的分段错误

在 Swift 4 中实现自定义解码器

在 Swift 中覆盖 UIScrollView 的委托属性(就像 UICollectionView 一样)

如何快速从另一个视图控制器重新加载表格视图

我可以让#selector 引用 Swift 中的闭包吗?