Animator
Drives an animator controller — the state machine that decides which clip plays. For building the controller itself, see the 2D Animation guide.
public class Player : GameEntity
{
private Animator? m_Anim;
protected override void OnCreate()
{
m_Anim = GetComponent<Animator>();
}
protected override void OnUpdate(float ts)
{
m_Anim?.SetFloat("Speed", System.Math.Abs(m_Velocity.X));
m_Anim?.SetBool("Grounded", m_Grounded);
}
public void Jump() => m_Anim?.SetTrigger("Jump");
}Parameters
Controller transitions are driven by named parameters you set from script.
| Method | Notes |
|---|---|
SetFloat(string name, float value) | For blend conditions like walk speed |
SetInt(string name, int value) | For discrete states like a weapon index |
SetBool(string name, bool value) | Stays where you put it |
SetTrigger(string name) | A one-shot pulse, consumed by the transition that fires on it |
ResetTrigger(string name) | Clears a trigger that was set but never consumed |
GetFloat(string name) | Reads a float parameter back |
GetInt(string name) | Reads an int parameter back |
GetBool(string name) | Reads a bool parameter back |
Bool or trigger?
A bool describes a lasting condition — Grounded, Crouching. A trigger describes a moment — Jump, Hit. Using a bool for a moment means remembering to clear it; using a trigger for a condition means it fires once and the state never comes back. ResetTrigger is for the case where you set a trigger and then the situation changed before any transition consumed it.
State
CurrentState
The name of the state the animator is in right now.
if (m_Anim.CurrentState == "Death")
DisableInput();NormalizedTime
How far through the current state's clip you are, where 0 is the start and 1 is the end. A looping clip keeps counting past 1.
if (m_Anim.CurrentState == "Attack" && m_Anim.NormalizedTime > 0.6f)
EnableHitbox();IsTransitioning
true while a transition between two states is in progress.
IsPlaying
true while the animator is running (not paused).
Playback
Play(string stateName, float normalizedTime = 0.0f)
Jumps straight to a state, ignoring transitions. Optionally starts partway through.
m_Anim.Play("Idle");
m_Anim.Play("Death", 0.5f); // start halfway inCrossFade(string stateName, float duration)
Blends into a state over duration seconds — the smooth counterpart to Play.
m_Anim.CrossFade("Run", 0.15f);Speed
A multiplier on playback speed. 1 is authored speed, 0.5 is half, 2 is double. Read and write.
m_Anim.Speed = m_Slowed ? 0.4f : 1.0f;Pause() / Resume()
Stop and restart playback where it is.
Reacting to state changes
Animator notifications are GameEntity overrides, not C# events — see Components for why.
protected override void OnAnimatorStateEntered(string stateName)
{
if (stateName == "Attack")
m_SwingSound?.Play();
}
protected override void OnAnimatorStateExited(string stateName) { }
protected override void OnAnimatorPose()
{
// Layer procedural motion on top of the sampled clip.
Translation += m_Recoil;
}Exited and Entered fire once per transition, in that order. OnAnimatorPose runs after the animator has written this frame's pose, which is what lets you add recoil, a look-at or breathing on top of a clip without the next frame's sample wiping it out.
There was once an event here
Earlier versions declared Animator.StateEntered as a C# event. Nothing could ever raise it, so subscribing did nothing at all. It was removed rather than left as a trap — use the overrides above.
Animation events
A clip's event track can call a method on your script by name. Mark the method so the engine will dispatch to it:
[AnimationEvent]
private void Footstep()
{
m_StepSound?.Play();
}
[AnimationEvent]
private void SpawnEffect(string effectName)
{
Particles.Spawn($"Effects/{effectName}.jparticle", Translation);
}Supported signatures are void F(), void F(string), void F(float) and void F(int). An unsupported signature is reported once in the log and the event is skipped — playback never crashes over it.
The attribute is required. A method without it can't be called from a clip, which keeps an animation from reaching arbitrary methods on a script that never opted in. See Attributes.
Animation.Sample(GameEntity entity, string clipPath, float time)
Applies one frame of a clip to an entity directly, with no animator involved — for posing something at a fixed moment. The entity needs whatever components the clip's tracks target.
Animation.Sample(this, "Animations/Wave.janim", 0.5f);See also
- 2D Animation — building sprite sheets, clips, and controllers
- GameEntity — the animator lifecycle hooks
- Attributes —
[AnimationEvent]