RealityKit Basics: Entities and Components
Taking a deeper look at creating entities with multiple components.
Overview
RealityKit uses an Entity Component System {ECS) pattern. We can think of an entity as an empty container and components as content/behaviors we can add to that container. Let’s look at two simple ways to create entities.
Create a entity manually
This will create a small red sphere. We create an entity, make a material, and generate a shape. Then we combine the mesh (shape) and the material to create a model component that we can add to our entity.
let subjectEntity = Entity()
subjectEntity.name = "Subject"
// Let's start with a material
var material = PhysicallyBasedMaterial()
material.baseColor.tint = .stepRed
material.roughness = 0.5
material.metallic = 0.0
// Then we will create a shape for our model
let shape = MeshResource.generateSphere(radius: 0.2)
// We can create a model component using a mesh (shape) and one or more materials
let model = ModelComponent(mesh: shape, materials: [material])
// Add the model component to the entity
subjectEntity.components.set(model)Using ModelEntity
ModelEntity is a convenient way to create an entity with a model, shapes, and material. This assumes we already have a material we can use.
let sphere = ModelEntity(
mesh: .generateSphere(radius: 0.03),
materials: [material])Adding a few more components
RealityKit has a lot of build-in component and we can even create our own. Let’s start by adding some components to support interactivity with our entity.
// visionOS will apply a hover effect component when we look at this entity
subjectEntity.components.set(HoverEffectComponent())
// InputTargetComponent will allow us to use system gestures such as tag and drag
subjectEntity.components.set(InputTargetComponent())
// Our entity must also have a CollisionComponent for gestures to work. There are a lot of other uses for collisions that we will cover later
subjectEntity.components.set(CollisionComponent(shapes: [ShapeResource.generateSphere(radius: 0.2)]))Adding our entities to the scene
If you try to run the code above nothing will happen. That is because we haven’t added our entities to the scene. We can add our subject entity to the RealityView content. Then we can add our second entity as a child of the subject.
// Any root entities should be added to content like this.
content.add(subjectEntity)
// Add the sphere as a child to the subject.
subjectEntity.addChild(sphere)
// content.add(sphere) ❌
// we don't need to add the sphere to the content since we are adding it as a child to the subjectBonus: adding a tap gesture
Let’s add a tap gesture to show that our hover, input, and collision components are working. You can learn more about system gestures on the Learn visionOS page.
.gesture(TapGesture()
.targetedToAnyEntity() // allows us to target any entity in a RealityView
.onEnded { value in
let currentTransform = value.entity.transform
let rotationDelta = simd_quatf(angle: .pi/12, axis: [0, 1, 0])
let newOrientation = currentTransform.rotation * rotationDelta
value.entity.setOrientation(newOrientation, relativeTo: nil)
}
)Video Demo
Full Example Code
struct Example039: View {
var body: some View {
RealityView { content in
// 1. Create a subject entity for our scene
let subjectEntity = Entity()
subjectEntity.name = "Subject"
// Let's start with a material
var material = PhysicallyBasedMaterial()
material.baseColor.tint = .stepRed
material.roughness = 0.5
material.metallic = 0.0
// Then we will create a shape for our model
let shape = MeshResource.generateSphere(radius: 0.2)
// We can create a model component using a mesh (shape) and one or more materials
let model = ModelComponent(mesh: shape, materials: [material])
// Add the model component to the entity
subjectEntity.components.set(model)
// Let's add some more components
// visionOS will apply a hover effect component when we look at this entity
subjectEntity.components.set(HoverEffectComponent())
// InputTargetComponent will allow us to use system gestures such as tag and drag
subjectEntity.components.set(InputTargetComponent())
// Our entity must also have a CollisionComponent for gestures to work. There are a lot of other uses for collisions that we will cover later
subjectEntity.components.set(CollisionComponent(shapes: [ShapeResource.generateSphere(radius: 0.2)]))
// 2. ModelEntity is a convenient way to create an entity with a model, shapes, and material.
material.baseColor.tint = .stepBlue // Hack: use the same material and change the color *
let sphere = ModelEntity(
mesh: .generateSphere(radius: 0.03),
materials: [material])
// Set the position of the sphere relative to the subject
sphere.setPosition([-0.25, 0.2, 0.1], relativeTo: subjectEntity)
// 3. Add our entities to the scene
// Make sure to add our subject to the scene. Any root entities should be added to content like this.
content.add(subjectEntity)
// Add the sphere as a child to the subject.
subjectEntity.addChild(sphere)
// content.add(sphere) ❌ we don't need to add the sphere to the content since we are adding it as a child to the subject
// * Note about the material hack above. Once a component is added to an entity, changes to it in code are not reflected on that entity. In the code above, we created a red material and added it to the subject. Then we changed the color to blue and it did not change the color of the subject. This pattern holds true for all components in RealityKit.
}
// You can learn a lot more about system gestures from our series on Input
.gesture(TapGesture()
.targetedToAnyEntity()
.onEnded { value in
let currentTransform = value.entity.transform
let rotationDelta = simd_quatf(angle: .pi/12, axis: [0, 1, 0])
let newOrientation = currentTransform.rotation * rotationDelta
value.entity.setOrientation(newOrientation, relativeTo: nil)
}
)
}
}Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision