Adding ModelComponent to Reality Composer Pro's "Primitive Shape" entity

Is there a way to give a "Primitive Shape" entity created through Reality Composer Pro a ModelComponent?

I have a custom ShaderGraphMaterial assigned to a primitive shape in my RC Pro scene hierarchy, and I'd like to tweak the inputs of this material programatically. I found a great example of the behavior I'm looking for here: https://developer.apple.com/videos/play/wwdc2023/10273/?time=1862

@State private var sliderValue: Float = 0.0

Slider(value: $sliderValue, in: (0.0)...(1.0))
    .onChange(of: sliderValue) { _, _ in
        guard let terrain = rootEntity.findEntity(named: "DioramaTerrain"),
                var modelComponent = terrain.components[ModelComponent.self],
                var shaderGraphMaterial = modelComponent.materials.first 
                    as? ShaderGraphMaterial else { return }
        do {
            try shaderGraphMaterial.setParameter(name: "Progress", value: .float(sliderValue))
            modelComponent.materials = [shaderGraphMaterial]
            terrain.components.set(modelComponent)
        } catch { }
    }
}

However, when I try applying this example to my use-case, my project's equivalent to this line fails to execute:

var modelComponent = terrain.components[ModelComponent.self]

The only difference I can see between my case and this example is my entity is a primitive shape, whereas the example uses a model reference to a .usdz file. Is there some way to update a primitive shape entity to contain this ModelComponent in its set of components so I can reference + update its materials programmatically?

Answered by cragsdale in 781605022

It turns out that the primitive shapes have the following structure ("TopSand" is what I named my primitive shape). ModelComponent isn't on the shape entity itself, but rather on it's first child.

To get the code from above working, I needed to access the child entity "usdPrimitiveAxis" and work with it's ModelComponent, ex:

guard let shapeEntity = rootEntity.findEntity(named: "TopSand"),
           let modelEntity = shapeEntity.children.first as? ModelEntity,
           var modelComponent = modelEntity.components[ModelComponent.self],
           var shaderGraphMaterial = modelComponent.materials.first as? ShaderGraphMaterial else { 
    return 
}

// Modify modelEntity as needed
Accepted Answer

It turns out that the primitive shapes have the following structure ("TopSand" is what I named my primitive shape). ModelComponent isn't on the shape entity itself, but rather on it's first child.

To get the code from above working, I needed to access the child entity "usdPrimitiveAxis" and work with it's ModelComponent, ex:

guard let shapeEntity = rootEntity.findEntity(named: "TopSand"),
           let modelEntity = shapeEntity.children.first as? ModelEntity,
           var modelComponent = modelEntity.components[ModelComponent.self],
           var shaderGraphMaterial = modelComponent.materials.first as? ShaderGraphMaterial else { 
    return 
}

// Modify modelEntity as needed
Adding ModelComponent to Reality Composer Pro's "Primitive Shape" entity
 
 
Q