beckp
beckp

Reputation: 147

Is there a way to programmatically change the material of an Entity that was created in Reality Composer?

I want to change the color of an entity programmatically after it was created in Reality Composer.

As Reality Composer does not create a ModelEntity (it creates a generic Entity), it does not appear that I have access to change its color. When I typecast to a ModelEntity, I now have access to the ModelComponent materials. However, when I try to add that to the scene I get a Thread 1: signal SIGABART error. Could not cast value of type 'RealityKit.Entity' (0x1fcebe6e8) to 'RealityKit.ModelEntity' (0x1fceba970). Sample code below.

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)
    }
}

Upvotes: 3

Views: 3311

Answers (1)

Andy Jazz
Andy Jazz

Reputation: 58043

Model entity is stored deeper in RealityKit's hierarchy, and as you said, it's Entity, not ModelEntity. So use downcasting to access mesh and 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)
    }
}

Also, this post and this one can be helpful.

Upvotes: 5

Related Questions