Using events with Manipulation Component
We can use events to modify the entity during the gesture or save state at the end.
Overview
Expanding on what we learned in Getting started with Manipulation Component, let’s take a look at events.
RealityKit has several new events that we can listen to.
WillBegin fires when manipulation starts. For example, changing from dynamic to kinematic physics, hiding a hover effect, deactivating children, etc.
_ = content.subscribe(to: ManipulationEvents.WillBegin.self) { event in
// Remove the hover effect when manipulating an entity
event.entity.components.remove(HoverEffectComponent.self)
}DidUpdateTransform can be useful for constraining the transform of the entity. For example, don’t allow an entity to move out of a fixed area or disallow rotation on an axis.
For an example, see Constrain position with ManipulationComponent
_ = content.subscribe(to: ManipulationEvents.DidUpdateTransform.self) { event in
// clamp, constrain, etc.
}DidHandOff can be useful if we need to apply hand-specific offsets to the entity.
_ = content.subscribe(to: ManipulationEvents.DidHandOff.self) { event in
// Apply offsets by using the pose of the hands
}WillRelease is fired just before manipulation ends. This can be a good place to reset visual effects. We use this to re-add the hover effect.
_ = content.subscribe(to: ManipulationEvents.WillRelease.self) { event in
let hover = HoverEffectComponent(.spotlight(.default))
event.entity.components.set(hover)
}WillEnd is fired at the end. The gesture is no longer updating the entity. This can be useful to reset physics or save transform data in app state.
_ = content.subscribe(to: ManipulationEvents.WillEnd.self) { event in
// persist transform data here
}Full Example Code
struct Example088: View {
// An entity we can manipulate
@State private var subject = createStepDemoBox()
var body: some View {
RealityView { content in
subject.position.y = -0.2
// We'll use configureEntity to set up input and collision on the subject
ManipulationComponent
.configureEntity(
subject,
hoverEffect: .spotlight(.default),
collisionShapes: [.generateBox(width: 0.25, height: 0.25, depth: 0.25)]
)
// Create the component and add it to the entity
let mc = ManipulationComponent()
// Add the component and
subject.components.set(mc)
content.add(subject)
// Manipulation Component Events
// *WillBegin* fires when manipulation starts
// For example, changing from dynamic to kinematic physics, hiding a hover effect, deactiving children, etc.
_ = content.subscribe(to: ManipulationEvents.WillBegin.self) { event in
// Remove the hover effect when manipulating an entity
event.entity.components.remove(HoverEffectComponent.self)
}
// *DidUpdateTransform* can be useful for constraining the transform of the entity
// For example, don't allow an entity to move out of fixed area or disallow rotation on an axis
_ = content.subscribe(to: ManipulationEvents.DidUpdateTransform.self) { event in
// For an example, see [Constrain position with ManipulationComponent](https://stepinto.vision/example-code/constrain-position-with-manipulationcomponent/)
}
// *DidHandOff* can be useful if we need to apply hand-specific offsets to the entity
_ = content.subscribe(to: ManipulationEvents.DidHandOff.self) { event in
// Apply offsets by using the pose of the hands
}
// *WillRelease* is fired just before manipulation ends
// This can be a good place to reset visual effects
// We use this to re-add the hover effect
_ = content.subscribe(to: ManipulationEvents.WillRelease.self) { event in
let hover = HoverEffectComponent(.spotlight(.default))
event.entity.components.set(hover)
}
// *WillEnd* is fired at the end. The gesture is no longer updating the entity
// This can be useful to reset physics or save transform data in app state
_ = content.subscribe(to: ManipulationEvents.WillEnd.self) { event in
// persist transform data here
}
}
.debugBorder3D(.white)
}
}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