This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

GS_Motion

Track-based animation and tween system — abstract base classes for motions, tracks, composites, assets, and proxies with a domain extension pattern.

GS_Motion is the framework’s central track-based animation system. It defines abstract base classes that domain gems extend with concrete track types — GS_UI extends it with 8 UI animation tracks (.uiam assets), and GS_Juice extends it with 2 feedback tracks (.feedbackmotion assets). The system handles playback timing, per-track easing, proxy-based entity targeting, and deep-copy runtime instancing from data assets.

For usage guides and setup examples, see The Basics: GS_Core.

 

Contents


Architecture

GS_MotionTrack (abstract base)
    ├── UiMotionTrack (GS_UI domain base)
    │       ├── UiPositionTrack
    │       ├── UiScaleTrack
    │       ├── UiRotationTrack
    │       ├── UiElementAlphaTrack
    │       ├── UiImageAlphaTrack
    │       ├── UiImageColorTrack
    │       ├── UiTextColorTrack
    │       └── UiTextSizeTrack
    └── FeedbackMotionTrack (GS_Juice domain base)
            ├── FeedbackTransformTrack
            └── FeedbackMaterialTrack

GS_MotionAsset (abstract base)
    ├── UiAnimationMotionAsset (.uiam)
    └── FeedbackMotionAsset (.feedbackmotion)

GS_MotionComposite (runtime instance)
    └── Created by asset's CreateRuntimeComposite()

Core Classes

ClassDescriptionPage
GS_MotionTrackAbstract base for all animation tracks — fields, lifecycle, virtual methods, extension guide.MotionTrack
GS_MotionPlayback engine — ticks tracks, computes per-track progress windows, applies easing, manages lifecycle.Motion Engine
GS_MotionCompositeRuntime deep-copy instance with proxy entity overrides — created from GS_MotionAsset.MotionComposite
GS_MotionAssetAbstract base for motion data assets — holds track definitions and creates runtime composites.MotionAsset
GS_MotionProxySerialized struct for track-to-entity redirection — allows designers to target named tracks at different entities.MotionProxy

Domain Extensions

GS_Motion is designed to be extended by domain gems. Each domain creates its own track hierarchy, asset type, and file extension.

DomainGemBase TrackConcrete TracksAsset Extension
UI AnimationGS_UIUiMotionTrackPosition, Scale, Rotation, ElementAlpha, ImageAlpha, ImageColor, TextColor, TextSize (8).uiam
FeedbackGS_JuiceFeedbackMotionTrackFeedbackTransformTrack, FeedbackMaterialTrack (2).feedbackmotion

Extension Pattern

To create a new motion domain:

  1. Create a domain base trackclass MyTrack : public GS_Core::GS_MotionTrack
  2. Create concrete tracks extending the domain base — each overrides Update(float easedProgress) and GetTypeName()
  3. Create a domain assetclass MyAsset : public GS_Core::GS_MotionAsset with vector<MyTrack*> m_tracks
  4. Create an instance wrapper struct (not a component) — holds Asset<MyAsset> + vector<GS_MotionProxy>, manages Initialize / Unload / Play / Stop
  5. Embed the wrapper — components embed the instance wrapper struct as a serialized field

Critical: All track vectors must use raw pointers: vector<MyTrack*>. Never use unique_ptr — O3DE SerializeContext requires raw pointers for polymorphic enumeration in the asset editor.


See Also

For conceptual overviews and usage guides:

For class references:

For domain extensions:


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.

1 - GS_MotionTrack

Abstract base class for all animation tracks — fields, lifecycle, and virtual methods for domain extension.

GS_MotionTrack is the abstract base class for all animation tracks in the GS_Motion system. Each track animates one aspect of an entity over a time window within a motion. Domain gems extend this with concrete track types — GS_UI provides 8 LyShine tracks, GS_Juice provides 2 feedback tracks.

For usage guides and setup examples, see The Basics: GS_Core.


Fields

FieldTypeDescription
m_idAZ::UuidUnique track identifier (auto-generated).
m_identifierAZStd::stringProxy label — if set, the track appears in the proxy list for entity override targeting.
curveTypeCurveTypeEasing curve applied to track progress (from the Curves utility library).
startTimefloatTime offset before the track begins playing (seconds).
durationfloatTrack playback duration (seconds).
startVarianceMinfloatMinimum random variance added to start time.
startVarianceMaxfloatMaximum random variance added to start time.

Lifecycle

Each track goes through a fixed lifecycle managed by the parent GS_Motion:

PhaseMethodDescription
InitializeInit(AZ::EntityId owner)Stores the owner entity. Called once when the motion is initialized.
StartStart()Called when the track’s time window begins.
UpdateUpdate(float easedProgress)Called each frame with eased progress (0 → 1). Override this in concrete tracks.
EndEnd()Called when the track’s time window completes.
UnloadUnload()Cleanup. Called when the motion is unloaded.

Virtual Methods

These methods must be overridden in concrete track implementations:

MethodReturnsDescription
Update(float easedProgress)voidApply the animation at the given eased progress value (0 → 1).
GetTypeName()AZStd::stringReturn the track’s display name for proxy labels in the editor.

Extension Guide

To create a new domain of animation tracks:

  1. Create a domain base track: class MyTrack : public GS_Core::GS_MotionTrack — this serves as the common base for all tracks in your domain.
  2. Create concrete tracks extending the domain base — each overrides Update(float easedProgress) to animate a specific property.
  3. Reflect the track class using O3DE’s SerializeContext and EditContext. The system discovers the new type automatically.

Critical: Track vectors must use raw pointers (vector<MyTrack*>). Never use unique_ptr — O3DE SerializeContext requires raw pointers for polymorphic enumeration in the asset editor.


See Also


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.

2 - GS_Motion

The playback engine — ticks through tracks, computes per-track progress windows, and manages motion lifecycle.

GS_Motion is the playback engine that drives animation tracks. It ticks through all tracks each frame, computes per-track progress windows based on start time and duration, applies easing curves, and calls Update(easedProgress) on each active track. It handles motion lifecycle from initialization through completion.

For usage guides and setup examples, see The Basics: GS_Core.


API Reference

MethodParametersReturnsDescription
PlayvoidBegin playback from the start.
PlayWithCallbackAZStd::function<void()> cbvoidPlay and invoke callback on completion.
StopvoidStop playback immediately.
InitializeAZ::EntityId ownervoidInitialize all tracks with the owner entity.
UnloadvoidUnload all tracks and clean up.

Fields

FieldTypeDescription
motionNameAZStd::stringDisplay name for the motion.
tracksvector<GS_MotionTrack*>The tracks in this motion.
loopboolWhether playback loops.
onCompletefunction<void()>Completion callback (set via PlayWithCallback).

How It Works

Each frame during playback:

  1. The motion calculates the global elapsed time.
  2. For each track, it computes the track-local progress based on startTime and duration.
  3. If the track is within its active window, the progress is eased using the track’s curveType.
  4. Update(easedProgress) is called on the track with the eased value (0 → 1).
  5. When all tracks complete, OnMotionComplete() is called.

Virtual Methods

MethodDescription
OnMotionCompleteCalled when playback finishes. Override in subclasses for custom teardown.

See Also


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.

3 - GS_MotionComposite

Runtime deep-copy motion instance with proxy entity overrides — created from GS_MotionAsset for per-entity playback.

GS_MotionComposite is the runtime instance of a motion, created from a GS_MotionAsset. It deep-copies all tracks so each entity gets independent playback state, and applies proxy overrides to redirect specific tracks to different entities in the hierarchy.

For usage guides and setup examples, see The Basics: GS_Core.


GS_MotionComposite extends GS_Motion. When an asset’s CreateRuntimeComposite() is called, all tracks are SC-cloned (serialization-context cloned) into a new composite instance. This ensures each entity playing the same motion has its own independent track state — no shared mutation.


API Reference

MethodParametersReturnsDescription
ApplyProxiesAZ::EntityId owner, vector<GS_MotionProxy> proxiesvoidMatches proxy trackIds to tracks and overrides the target entity for each matched track.

How It Works

  1. Creation: GS_MotionAsset::CreateRuntimeComposite() deep-copies all asset tracks into a new composite.
  2. Proxy Application: ApplyProxies() walks the proxy list, matching each proxy’s m_trackId to a track’s m_id. Matched tracks redirect their owner entity to the proxy’s m_proxyEntity.
  3. Playback: The composite plays exactly like a regular GS_Motion — it ticks tracks, applies easing, and calls Update().
  4. Cleanup: On Unload(), the composite cleans up all deep-copied tracks.

See Also


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.

4 - GS_MotionAsset

Abstract base for motion data assets — holds track definitions and creates runtime composites.

GS_MotionAsset is the abstract base class for motion data assets. Domain gems extend this with their own asset type and file extension — GS_UI creates UiAnimationMotionAsset (.uiam), GS_Juice creates FeedbackMotionAsset (.feedbackmotion). Assets are created and edited in the O3DE Asset Editor.

Extends AZ::Data::AssetData. All subclasses require GS_AssetReflectionIncludes.h in their header — see Serialization Helpers.

For usage guides and setup examples, see The Basics: GS_Core.


API Reference

MethodReturnsDescription
GetTrackInfosvector<GS_TrackInfo>Returns track UUID + label pairs for proxy list synchronization in the editor.
CreateRuntimeCompositeGS_MotionComposite*Factory — deep-copies all asset tracks into a new runtime GS_MotionComposite instance.

GS_TrackInfo

Lightweight struct used for proxy synchronization between asset tracks and instance proxy lists.

FieldTypeDescription
idAZ::UuidTrack identifier (matches the track’s m_id).
labelAZStd::stringTrack display name (from GetTypeName()).

Domain Extensions

DomainGemAsset ClassExtensionTracks
UI AnimationGS_UIUiAnimationMotionAsset.uiam8 LyShine-specific tracks
FeedbackGS_JuiceFeedbackMotionAsset.feedbackmotion2 feedback tracks

Extension Guide

To create a new domain asset type:

  1. Create class MyAsset : public GS_Core::GS_MotionAsset with vector<MyDomainTrack*> m_tracks. Include GS_AssetReflectionIncludes.h in your asset’s header — see Serialization Helpers.
  2. Implement GetTrackInfos() — iterate tracks and return UUID + label pairs.
  3. Implement CreateRuntimeComposite() — deep-copy tracks into a new GS_MotionComposite.
  4. Register the asset type in your gem’s DataAssetsSystemComponent.
  5. Add a .setreg entry for the asset processor to recognize your file extension.

Critical: Track vectors must use raw pointers (vector<MyTrack*>). O3DE SerializeContext requires raw pointers for polymorphic enumeration.


See Also


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.

5 - GS_MotionProxy

Serialized struct for track-to-entity redirection — allows designers to target named tracks at different entities.

GS_MotionProxy is a serialized struct that allows designers to redirect a named track to a different entity in the hierarchy. This enables a single motion asset to animate multiple entities — for example, a UI animation that moves one element while fading another.

For usage guides and setup examples, see The Basics: GS_Core.


Fields

FieldTypeDescription
m_trackIdAZ::UuidReferences the track’s m_id. Matched during ApplyProxies().
m_labelAZStd::stringRead-only display label (synced from track info at edit time via GetTrackInfos()).
m_proxyEntityAZ::EntityIdThe entity this track should target instead of the motion’s owner entity.

How It Works

  1. Edit time: The proxy list syncs from the asset’s track info. Each track with an m_identifier (non-empty label) appears as a proxy slot in the inspector.
  2. Designer assignment: The designer drags an entity reference into the proxy’s m_proxyEntity field.
  3. Runtime: When GS_MotionComposite::ApplyProxies() runs, it matches each proxy’s m_trackId to a track’s m_id and overrides that track’s target entity.
  4. Playback: The track now animates the proxy entity instead of the motion’s owner.

Usage

Proxies are embedded in instance wrapper structs (e.g., UiAnimationMotion, FeedbackMotion) alongside the asset reference. Components serialize the proxy list, and the wrapper handles synchronization with the asset.

Only tracks with a non-empty m_identifier appear in the proxy list. Tracks without an identifier always animate the owner entity.


See Also


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.