Quick answer: Assign the Timeline asset to the Playable Director, set the animated object in the Track Bindings panel, ensure Play On Awake is enabled (or call director.Play() explicitly), and remove any AnimatorOverrideController that conflicts with Timeline’s Animator control.
You drop an Animation Track into a Timeline, scrub it in the editor and everything looks fine — then you hit Play and nothing moves. The Playable Director sits there doing nothing, no errors in the Console, no warnings, just silence. This is one of those Unity bugs that can swallow an entire afternoon because every individual system looks correct in isolation. This guide works through every root cause in order of likelihood so you can stop guessing and ship.
The Symptom
The clearest sign is a Timeline that appears to run — the Playable Director component shows a non-zero time value ticking up in Play Mode — but the objects in the scene refuse to move. A closely related variant is a Timeline that never starts at all: time stays at 0, and calling director.time in a debug log confirms it. A third variant is the Timeline that fires exactly once on the first run but never again after a scene reload.
All three variants share most of the same causes, just triggered at different points in the execution order. Work through this list top-to-bottom and you will find the culprit.
What Causes This
No Timeline asset assigned. The Playable Director component has a Playable field at the top of the Inspector. If that field reads None (Playable Asset), the director has nothing to play. Drag your .playable asset into that slot. This is easy to miss after duplicating a GameObject — the component copies but the asset reference does not always follow.
Play On Awake disabled. By default, Playable Director sets Play On Awake to true. If you unchecked it to control playback in code and then forgot to call Play(), the Timeline never starts. Either re-enable the checkbox or add an explicit call:
using UnityEngine;
using UnityEngine.Playables;
public class CutsceneTrigger : MonoBehaviour
{
[SerializeField] private PlayableDirector director;
public void StartCutscene()
{
if (director == null) return;
director.time = 0; // rewind before playing
director.Play();
}
}
Track binding not set. Every Animation Track needs a binding — the Animator component that the track drives. Open the Timeline window, select the track, and look at the left-hand binding slot. If it shows a None or a missing object reference, the track runs but drives nothing. Assign the correct Animator (or GameObject with an Animator) in that slot. The binding is stored per-scene, so prefab-based Timelines need the binding re-established in each scene that uses them.
AnimatorOverrideController conflict. If the Animator on the bound object uses an AnimatorOverrideController at runtime, Timeline and the override controller both try to drive the same Animator. Timeline’s Playable Graph loses control of the clips:
// Problematic pattern — override applied before Timeline plays
void Start()
{
AnimatorOverrideController aoc = new AnimatorOverrideController(baseController);
animator.runtimeAnimatorController = aoc; // this breaks Timeline
}
// Fixed pattern — store the original and restore after Timeline
RuntimeAnimatorController originalController;
void Awake()
{
originalController = animator.runtimeAnimatorController;
}
public void BeforeTimeline()
{
// Restore the base controller so Timeline can take over
animator.runtimeAnimatorController = originalController;
director.Play();
}
public void AfterTimeline()
{
// Re-apply override when cutscene ends
AnimatorOverrideController aoc = new AnimatorOverrideController(originalController);
animator.runtimeAnimatorController = aoc;
}
Signal receiver not connected. If your Timeline relies on Signal Emitters to trigger game events and those events are what ultimately start the next clip or enable the animated object, a missing Signal Receiver on the target GameObject will silently swallow the signal. Open each Signal Emitter in the Timeline, confirm the Signal Asset is assigned, and verify the receiving GameObject has a Signal Receiver component with a matching reaction wired up.
The Fix
Run through this checklist in order. Each item takes under a minute to verify:
- Inspect the Playable Director: confirm the Playable field has a non-null
.playableasset. - Check Play On Awake. If it’s off, add an explicit
director.Play()call in the right lifecycle method. - Open the Timeline window with the Playable Director selected. Check every Animation Track’s left-hand binding slot for a missing reference.
- Search the project for
AnimatorOverrideController— if one is set on the same Animator that Timeline binds, restructure so they don’t overlap. - If using Signal Emitters, confirm each Signal Receiver exists and is wired.
“A Timeline that runs but drives nothing produces zero Console output. Add a single
Debug.Loginside a Signal Receiver to confirm the Timeline is at least reaching that point — it immediately tells you whether the issue is playback or binding.”
The Invisible Animation Problem
There is a particularly frustrating variant where the Timeline is genuinely running and the binding is correct, but nothing appears to change. The cause is almost always that the animated property is already at the value the first keyframe sets. If your Animation Track animates Position.x from 0 to 5 and the object starts at Position.x = 0, the first frames of the animation are a no-op. Scrub forward in the Timeline window to confirm the object does move later in the clip.
A related cause is animating the wrong object. A Transform Position track bound to a child object when you intended the parent root will move the child — which may be invisible if the child is an empty pivot — while the visible mesh stays put. Check the binding target carefully.
Wrap Mode and Post-Playback State
If the animation plays once but the object snaps back to its original position the moment the Timeline finishes, the Playable Director’s Wrap Mode is set to None and Extrapolation on the Animation Track is set to None rather than Hold. Select the Animation Track in the Timeline window, open its settings, and change the post-extrapolation from None to Hold. Alternatively, set the Playable Director’s Extrapolation Mode to Hold in the Inspector.
// Lock final pose via code after the director finishes
director.stopped += OnTimelineStopped;
void OnTimelineStopped(PlayableDirector d)
{
// Manually keep the Animator in the final state
animator.SetTrigger("CutsceneComplete");
// Or disable the Animator and manually set the transform
}
Debugging with the Playable Graph Visualizer
Unity’s Playable Graph Visualizer (available via the Package Manager) lets you inspect the live graph of Playables while in Play Mode. Open it from Window > Analysis > PlayableGraph Visualizer, select your Playable Director from the dropdown, and you can see whether the AnimationMixerPlayable is receiving input from your clips. A gray or disconnected node confirms a missing binding. A node with a weight of 0 on the mixer indicates a blend issue rather than a connectivity issue. This tool turns guesswork into a five-second diagnosis.
Related Issues
If fixing the Timeline binding reveals a second problem — the animation plays but character IK breaks, or the Timeline-driven camera cuts to the wrong position — those are typically Cinemachine Brain priority conflicts or IK weight not being reset after Timeline releases control of the Animator. The Playable Director’s Update Method (Game Time vs. DSP Time vs. Unscaled Game Time) can also cause Timeline to run at the wrong speed when Time.timeScale is not 1, which looks identical to a broken animation track on first inspection.
Once you’ve fixed the binding and confirmed the Timeline runs cleanly, consider capturing a Bugnet report the first time a player hits a related animation regression — silent runtime animation failures are exactly the kind of bug that slips through QA.