Lab 066 – First look at Mesh Instances Component
Useful for creating efficient copies of meshes in vast quantities.
Overview
The first thing to keep in mind when using this component is the name. This component creates instance of meshes, not entities. If you need to create a complete copy of an entity with all components and children, then use Entity.clone().
MeshInstancesComponent takes a bit of work to set up and use. We can specify a number of instances using LowLevelInstanceData.
let instances = try LowLevelInstanceData(instanceCount: 10)Then we need to get the mesh / part that we want to copy. This can take some trial and error depending on the structure of the entity. For primitive entities like spheres and cubes we can get the first part index.
meshInstancesComponent[partIndex: 0] = .init(data: instances)We can process the instances, making changes to the transform of each one as needed based on the requirements of our app.
instances.withMutableTransforms { transforms in
for i in 0..<instanceCount {
// Do something with the transform of each instance
}
}Here is a minimal usage:
let instanceCount = 10
var meshInstancesComponent = MeshInstancesComponent()
do {
// 1. specify a number of instances
let instances = try LowLevelInstanceData(instanceCount: instanceCount)
// 2. get the mesh / part to copy
meshInstancesComponent[partIndex: 0] = .init(data: instances)
// Loop over each instance and update the transform
instances.withMutableTransforms { transforms in
for i in 0..<instanceCount {
let offset: Float = 0.05 * Float(i)
var transform = Transform()
transform.translation = [offset, offset, offset]
transforms[i] = transform.matrix
}
}
// Add the component to the entity
entity.components.set(meshInstancesComponent)
} catch {
print("error creating instances = \(error)")
}Video Demo
Example Code
The code for this example uses a tag gesture to create and attach a new instance of the component. Each time we tap the main entity, we add to the number of instances, then attach a new copy of MeshInstancesComponent. We could also capture the current MeshInstancesComponent from an entity, modify it, and assign it back. Perhaps we’ll dive deeper into that in another lab.
struct Lab066: View {
@State var instanceCount = 1
@State var offset: Float = 0.05
var body: some View {
RealityView { content in
// Load a scene
guard let scene = try? await Entity(named: "InstanceLab", in: realityKitContentBundle) else { return }
content.add(scene)
// Load an entity and set it up for input
guard let subject = scene.findEntity(named: "Subject") else { return }
subject.components.set(InputTargetComponent())
subject.components.set(HoverEffectComponent())
subject.components
.set(CollisionComponent(shapes: [.generateBox(width: 0.1, height: 0.1, depth: 0.1)], isStatic: false))
// When we tap on the subject, we'll create create new instances
let tapGesture = TapGesture()
.onEnded({ [weak subject] _ in
guard let subject = subject else { return }
createInstances(entity: subject)
})
let gestureComponent = GestureComponent(tapGesture)
subject.components.set(gestureComponent)
subject.position = .init(x: 0, y: -0.3, z: 0)
}
.toolbar {
ToolbarItem(placement: .bottomOrnament, content: {
Text("Instances: \(instanceCount)")
})
}
}
func createInstances(entity: Entity) {
instanceCount += 1 // Add another instance each time this is run
// Create and set up the component
var meshInstancesComponent = MeshInstancesComponent()
do {
let instances = try LowLevelInstanceData(instanceCount: instanceCount)
// The tricky part can be getting the correct part index
meshInstancesComponent[partIndex: 0] = .init(data: instances)
// Loop over each instance and update the transform
instances.withMutableTransforms { transforms in
for i in 0..<instanceCount {
// For this example, we'll only edit the position / translation. We can also edit the scale and rotation if needed.
let offset: Float = 0.05 * Float(i)
var transform = Transform()
transform.translation = [offset, offset, offset]
transforms[i] = transform.matrix
}
}
entity.components.set(meshInstancesComponent)
} catch {
print("error creating instances = \(error)")
}
}
}Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more labs from Step Into Vision.

Follow Step Into Vision