Есть ли способ программно изменить материал сущности, созданной в Reality Composer?

Я хочу программно изменить цвет объекта после его создания в Reality Composer.

Поскольку Reality Composer не создает ModelEntity (он создает общий Entity), похоже, что у меня нет доступа для изменения его цвета. Когда я привожу тип в ModelEntity, у меня теперь есть доступ к материалам ModelComponent. Однако, когда я пытаюсь добавить это в сцену, я получаю ошибку Thread 1: signal SIGABART. Не удалось преобразовать значение типа RealityKit.Entity (0x1fcebe6e8) в RealityKit.ModelEntity (0x1fceba970). Пример кода ниже.

import UIKit
import RealityKit

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Load the "Box" scene from the "Experience" Reality File
        let boxAnchor = try! Experience.loadBox()
    
        // Typecast Steelbox as ModelEntity to change its color
        let boxModelEntity = boxAnchor.steelBox as! ModelEntity
    
        // Remove materials and create new material
        boxModelEntity.model?.materials.removeAll()
    
        let blueMaterial = SimpleMaterial(color: .blue, isMetallic: false)
        boxModelEntity.model?.materials.append(blueMaterial)
    
        // Add the box anchor to the scene
        arView.scene.anchors.append(boxAnchor)
    }
}

person beckp    schedule 06.03.2021    source источник


Ответы (1)


Сущность модели хранится глубже в иерархии RealityKit, и, как вы сказали, это Entity, а не ModelEntity. Поэтому используйте понижающее преобразование для доступа к mesh и materials:

import UIKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let boxScene = try! Experience.loadBox()
        print(boxScene)
        
        let modelEntity = boxScene.steelBox?.children[0] as! ModelEntity
        let material = SimpleMaterial(color: .green, isMetallic: false)
        modelEntity.model?.materials = [material]
        
        let anchor = AnchorEntity()
        anchor.scale = [5,5,5]
        modelEntity.setParent(anchor)
        arView.scene.anchors.append(anchor)
    }
}
person Andy Fedoroff    schedule 06.03.2021
comment
Я добавил дочерний индекс в код, который я опубликовал выше, и он работал с использованием существующей привязки Reality Composer. Я боролся с этим часами, спасибо! Мне нужно больше узнать о детях. Команда печати на сцене также является отличным советом. - person beckp; 07.03.2021
comment
Рад по этому поводу)) Для сцены бокса вы также можете использовать индекс boxScene.children[0].children[0].children[0].children[0] вместо boxScene.steelBox?.children[0]. - person Andy Fedoroff; 07.03.2021