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?
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