Chris
Chris

Reputation: 2907

RealityKit Change USDZ diffuse material at runtime

I am loading a USDZ model with RealityKit in Swift. The model loads fine with it's texture.

However, I am unable to change the diffuse property of the material, the material always comes back as AnyMaterial.

I can override the material completely with a SimpleMaterial or I can change the USDZ diffuse colour before running the app, but can't seem to do this at run time, any ideas?

I just want to be able to change the one property

/*
Find an entity within the parent, and find the material, test to try and change it's material
**/
private func updateColor(entity: Entity) {

    guard
        let found = entity.findEntity(named: "MyItem"),
        var modelComponent = found.components[ModelComponent] as? ModelComponent,
        let existingMaterial = modelComponent.materials.first else {
        return
    }

    // This is `AnyMaterial` - no diffuse property
    // What can I use here to change the diffuse?
    modelComponent.materials = [existingMaterial]

    // Change to yellow for testing
    //var material = SimpleMaterial()
    //material.baseColor = .color(.yellow)
    //modelComponent.materials = [material]

    found.components.set(modelComponent)
}

Upvotes: 4

Views: 3141

Answers (1)

Andy Jazz
Andy Jazz

Reputation: 58093

In RealityKit you can change material at runtime but you can't animate its parameters.

Here's a .baseColor instance property that works in RealityKit 1.0 and 2.0:

import SwiftUI
import RealityKit

struct ContentView: View {
    var body: some View {
        ARContainer().ignoresSafeArea()
    }
}

struct ARContainer: UIViewRepresentable {

    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {
        
        let modelAnchor = try! Experience.loadBox()
        modelAnchor.steelBox!.scale *= 5
        arView.scene.anchors.append(modelAnchor)
        
        let model = modelAnchor.steelBox!.children[0] as! ModelEntity
                
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
            var material = SimpleMaterial()
            material.baseColor = try! .texture(.load(named: "tex.png"))
            
            var comp: ModelComponent = model.components[ModelComponent.self]!
            comp.materials = [material]
            model.components.set(comp)
        }
        return arView
    }        
    func updateUIView(_ uiView: ARView, context: Context) { }
}


In RealityKit 2.0 for iOS 15 you can setup material's color and texture slightly differently:

var material = SimpleMaterial()

material.color =  .init(tint: .green, texture: nil)

Upvotes: 14

Related Questions