---
title: Automatically animating RealityKit entities
framework: realitykit
role: article
role_heading: Article
path: realitykit/automatically-animating-realitykit-entities
---

# Automatically animating RealityKit entities

Invoke implicit animations by setting the entity’s desired end state.

## Overview

Overview When you build 3D experiences with RealityKit, you often animate changes to an entity’s position, rotation, scale, or other properties. You can animate entity properties explicitly by creating an AnimationResource. RealityKit can also animate changes automatically using implicit animations, which let you describe only the desired end state inside a closure. RealityKit offers two closure-based approaches to implicit animation: Both approaches can animate properties for the following component types: Transform OpacityComponent ModelComponent ParticleEmitterComponent BillboardComponent DirectionalLightComponent PointLightComponent SpotLightComponent Animate entities without SwiftUI state Use animate(_:body:completion:) to animate entity properties without any SwiftUI state binding. Pass an Animation value and a closure that sets the properties you want to change. RealityKit interpolates each property from its current value to the new one using the animation you specify. Often, you can get the animation you want by using one of the static type classes on Animation, like linear or easeOut, rather than manually building a custom Animation. The following example moves an entity to a new position over one second using a linear animation to give a consistent speed throughout: Entity.animate(.linear(duration: 1.0)) {     entity.position = SIMD3<Float>(0, 1.5, -2) } The animate(_:body:completion:) method works without a RealityView update closure or a SwiftUI state binding. Animate entities in a RealityView update closure Use animate(body:completion:) inside a RealityView update closure to animate entity changes in response to SwiftUI state changes. Because this method derives its animation from the current SwiftUI transaction, attach an animation to the State variable that triggers the update. Bind the animation to your state variable using the animation(_:) modifier on a Binding. @State private var isScaled = false

var body: some View {     VStack {         RealityView { content in             // Add entities during initial setup.         } update: { content in             guard let entity = content.entities.first else { return }

content.animate {                 if isScaled {                     entity.components[Transform.self]?.scale = SIMD3<Float>(repeating: 2)                 } else {                     entity.components[Transform.self]?.scale = SIMD3<Float>(repeating: 1)                 }             }         }

Toggle("Scale", isOn: $isScaled.animation(.linear(duration: 1.0)))     } } The .animation(.linear(duration: 1.0)) modifier on $isScaled attaches an animation to the binding. When isScaled changes, RealityView calls the update closure within a transaction that carries this animation. The animate(body:completion:) call applies that animation to the property changes inside the closure. important: Call animate(body:completion:) only inside the update closure, not the make closure. The method relies on a SwiftUI transaction, which is only available during an update pass. Calling it during initial setup has no effect and logs a fault. Animate multiple properties You can change multiple properties inside a single animate closure. RealityKit creates a separate animation for each property and drives them all with the same timing. The following example animates an entity’s position, scale, and opacity at the same time: Entity.animate(.easeInOut(duration: 1.5)) {     entity.components[Transform.self]?.translation = SIMD3<Float>(0, 2, -3)     entity.components[Transform.self]?.scale = SIMD3<Float>(repeating: 1.5)     entity.components[OpacityComponent.self]?.opacity = 0.5 } important: When you animate Transform properties, set them together through entity.components[Transform.self] rather than setting position, scale, and orientation individually. Setting these convenience properties separately inside the closure generates independent animations that conflict, producing unexpected results. Respond to animation completion Both animate(_:body:completion:) and animate(body:completion:) accept an optional completion closure. RealityKit calls this closure when the animation finishes. The completion closure also runs if a new animation begins on the same property before the current animation finishes. Use the completion handler to chain animations or trigger follow-up logic. The following code example moves the entity to a new position, and the completion handler moves the entity back to the origin: Entity.animate(.easeIn(duration: 0.8)) {     entity.components[Transform.self]?.translation = SIMD3<Float>(0, 1.5, -2) } completion: {     Entity.animate(.easeOut(duration: 0.8)) {         entity.components[Transform.self]?.translation = .zero     } }

## See Also

### Animation playback

- [AnimationResource](realitykit/animationresource.md)
- [AnimationLibraryComponent](realitykit/animationlibrarycomponent.md)
- [AnimationLibraryComponent.AnimationCollection](realitykit/animationlibrarycomponent/animationcollection.md)
- [AnimationEvents](realitykit/animationevents.md)
- [AnimationPlaybackController](realitykit/animationplaybackcontroller.md)
- [AnimationRepeatMode](realitykit/animationrepeatmode.md)
