PlayMaker 2 Integration
01 What This Add-on Does
JuiceBox is a node-based animation tool. You build a sequence in its graph editor from tweens, follows, swings, shakes, waits and loops, point it at any GameObject, and it plays. This package is the bridge: everything you author in that graph becomes something a PlayMaker 2 FSM can start, stop and steer.
Installing it adds a JuiceBox category to the PlayMaker 2 action browser. Any state can fire a hit flash, a bounce, a screen shake or a UI transition, then carry on the moment it finishes. No code, no glue scripts, no coroutines.
The design goal is that neither half of the work sends you back to a code editor. The animation is authored in a graph, the gameplay logic lives in a state machine, and because both are visual you iterate on timing and feel by playing the scene rather than by recompiling.
This is an integration, not an animation system. The motion itself is authored in JuiceBox. If you have not built a sequence yet, start with the Pro quick start — this page assumes you have an animation with at least one named sequence on it.
02 Requirements and Installation
- JuiceBox - PRO — the animation system. Sequence handles, runtime parameters and mid-run retiming are Pro features, and the actions here are built on them.
- PlayMaker 2 — sold separately by Hutong Games. This package targets PlayMaker 2 only; it does not work with PlayMaker 1.
- Unity 2022.3.62 or newer.
Import the package and the actions appear. There is no setup window, no scene object to add, and nothing to configure.
The package ships in its own folder with its own assembly definitions
(JuiceBox.PlayMaker and JuiceBox.PlayMaker.Editor) and modifies no
JuiceBox or PlayMaker file. Both can be updated independently, and the package drops into an
existing PlayMaker project without touching FSMs you have already built.
03 The Actions at a Glance
Ten actions, all under the JuiceBox category.
| Action | What it does |
|---|---|
| Play Sequence | Starts a sequence, restarting it if it is already running. |
| Play Sequence Unique | Starts a sequence with a rule for what to do when it is already running. |
| Wait For Sequence | Holds the rest of the state's actions until a run ends. |
| Stop Sequence | Ends a run, one sequence, or everything on the animation. |
| Pause Sequence | Holds a run in place at the value it had reached. |
| Resume Sequence | Restarts a paused run from where it was held. |
| Is Sequence Running | Sends a true or false event depending on whether something is running. |
| Get Progress | Reads how far a run has advanced, from 0 to 1. |
| Set Timescale | Changes playback speed. Zero holds; negative runs backwards. |
| Set Parameter | Pushes an FSM variable into a named sequence parameter. |
04 Choosing the Animation and the Sequence
Most actions start with an Animation field. It defaults to the owner of the FSM, so if the JuiceBoxAnimation sits on the same GameObject as the FSM you can leave it alone. The field also accepts a GameObject variable, in which case the first JuiceBoxAnimation found on that object is used.
The actions that start a sequence then offer a Lookup choice:
- By Name — the sequence name as authored in the graph editor. An exact match wins; failing that, case is ignored.
- By Index — the sequence's position in the JuiceBox component, counting from 0.
Prefer By Name. Reordering sequences in the graph editor changes what an index points at, and nothing will warn you — the FSM will simply start playing a different animation. Use By Index only where sequences are generated or genuinely positional.
05 Play Sequence
Starts a sequence. If that sequence is already running, it restarts from the beginning.
Beyond the animation and sequence selectors, three optional fields do most of the useful work:
Parameter
Parameter Name and Parameter Value override one sequence
parameter for this run only. Leave the name empty to use the values authored in the graph. The
value accepts Float, Int, String, Vector2, Vector3, Vector4, Quaternion and Rect. This is the
easy way to make one animation serve many cases — a single Popup sequence
that takes its target height from the FSM, rather than six near-identical sequences.
Store Handle
Writes a Sequence Handle naming this particular run into an FSM variable. Every later action that takes a handle can then act on this run alone. See Sequence Handles.
Stop On Exit
Off by default, which means a sequence outlives the state that started it. That is usually what you want: a state fires a hit flash and immediately transitions on, and the flash finishes on its own. Turn it on when the animation should only last as long as the state does — a charge-up that must stop the moment the button is released, for example.
Play Sequence does not wait. It starts the run and the state moves on to the next action immediately. To hold the state until the animation ends, follow it with Wait For Sequence.
06 Play Sequence Unique
The retrigger-safe play. It takes everything Play Sequence takes, plus a Behavior that decides what happens when the sequence is already running on that target:
| Behavior | Result |
|---|---|
| Abort | The new call is dropped. The run already in flight continues undisturbed. This is the default. |
| Overwrite | The running one is ended and the new call starts from the beginning. |
| Wait | The new call queues behind the running one and starts when it finishes. |
This is what a spam-clicked button or a fast-repeating hit reaction needs. Each behavior maps to a different intent: Abort for something that should play out once and not stutter, Overwrite for a reaction that should always restart on the newest hit, and Wait for something that must be seen in full every time, such as a queue of notification pop-ins.
Wait returns a handle to a run that has not started yet. That handle is valid and can be passed straight to Wait For Sequence, which will hold until the queued run has both started and finished.
07 Wait For Sequence
Holds the rest of the state's actions until a run ends, then lets the state continue. It takes a single Handle, which normally comes from the Store Handle field of a play action in the same state.
A run ends when it finishes, when it is stopped, or when its owner is destroyed — all three release the wait, so a destroyed target cannot strand an FSM. A handle that names no run at all finishes immediately.
The wait is driven by JuiceBox's completion callback rather than by polling whether the run is running. That distinction matters for Play Sequence Unique with the Wait behavior: such a handle names a run that is valid but has not started yet, and a polling implementation would read it as already finished and fall straight through.
State: "Hit Reaction"
1. Play Sequence Flash → Store Handle: hitRun
2. Wait For Sequence hitRun
3. Send Event HIT_DONE
08 Sequence Handles
Sequence Handle is a PlayMaker variable type this package adds. It names one live run — not a sequence, and not an animation, but one specific playback of one sequence that is happening right now. Because it is an ordinary PlayMaker variable it passes between states, and in and out of FSM templates, like any other.
That is what lets you hold one animation and stop, pause, retime or read that run alone while everything else on the same object keeps playing.
Actions that take a handle require an actual variable rather than an inline value, so create a Sequence Handle variable on the FSM and point both the producing and consuming actions at it.
Handles are never saved. A handle names a run that exists only while the game is playing, so it is deliberately not serialized. A handle that survives a domain reload or a saved state reads as empty, and every action that receives an empty handle does nothing rather than failing. This is intentional: restoring a stale handle would be worse, because the id could by then name a different live run.
09 Stop, Pause, and Resume
These three share one Mode field that decides what to act on:
| Mode | Acts on |
|---|---|
| Handle | The one run the handle names. The Animation field is not needed. |
| Named Sequence | Every run of that sequence on the animation. |
| Sequence Index | Every run of the sequence at that position. |
| Whole Animation | Every sequence on the animation. |
Pause holds a run where it is, leaving its target at the value it had reached. Resume picks that run up from the same point.
Stop leaves the animated values wherever they were. It does not restore them to where they started. If you stop a fade half way, the object stays half faded. To return something to a known state, play a sequence that animates it back, or use a JuiceBox snapshot.
10 Is Sequence Running
Sends one of two events depending on whether something is running. It offers the same four modes as the stop and pause actions, and defaults to Named Sequence. In Whole Animation mode it is true if any sequence on the animation is running.
Because it is an ordinary true/false action it slots into a transition like any other, which makes a double-fired or stuck animation visible as normal FSM flow rather than something you have to guess at.
11 Get Progress
Reads how far a run has advanced. It takes a Handle and writes to Store Progress, a float from 0 to 1. Set the action's Update option to Every Frame and it will drive a fill image or a progress bar directly.
Store Elapsed Time is optional and reports the animation time the run has advanced, not counting time it spent paused or waiting.
Progress reads −1 once the handle no longer names a live run. That is deliberate rather than a quirk: clamping to 0 would make a finished run and a run that has not started yet report the same value, and a fill bar needs to tell those apart. Test for a negative value to detect "no longer running".
12 Set Timescale
A speed multiplier. 1 is unchanged, 0 holds the animation in place, and a negative value runs it backwards.
It offers two modes rather than the four the run-control actions have: Handle retimes one run, and Whole Animation retimes every sequence on the animation. There is no retime-by-sequence-name mode, because the JuiceBox runtime does not expose a per-sequence-name timescale.
Setting zero is a genuine pause-in-place that keeps the run addressable, and reversing is the cheapest way to get a close animation out of an open animation without authoring a second sequence.
13 Set Parameter
Pushes an FSM variable into a named sequence parameter on a running run. It takes a Handle, a Parameter Name as authored in the graph editor (case is ignored), and a Value.
Set the action's Update option to Every Frame and the animation follows your FSM continuously, so a health bar, a charge meter or an aim offset tracks game state with no glue scripts in between.
Supported value types:
| Type | Type | Type | Type |
|---|---|---|---|
| Float | Int | String | Vector2 |
| Vector3 | Vector4 | Quaternion | Rect |
The action does nothing while the handle's run is not running, so it is safe to leave updating every frame across states where the animation has finished. Passing a type that is not in the list above logs a runtime error naming the supported set — once per run, not once per frame.
14 Variable Types
The package adds two PlayMaker variable types. Both work as FSM template inputs and outputs.
| Variable | Holds |
|---|---|
| Sequence Handle | One live run, as described in section 8. Not serialized. |
| JuiceBox Animation | A reference to a JuiceBoxAnimation component. A field of this type also accepts a GameObject variable, resolving to the first JuiceBoxAnimation on it. |
Being template-compatible is what makes a reusable "play and wait" template possible: the template takes a JuiceBox Animation and a sequence name in, and hands a Sequence Handle back out.
15 Debugging in the FSM Editor
While the game is playing, the play and wait actions show live run information on the action itself in the FSM Editor, so you can watch a sequence advance inside the state that started it. Wait For Sequence and Get Progress also drive PlayMaker's action progress bar from the run's own progress.
For anything you need in FSM logic rather than in the inspector, Is Sequence Running and Get Progress expose the same state as ordinary events and variables.
16 Notes and Limitations
- Sequence handles are runtime-only. They are not saved and do not survive a domain reload. Treat them as live references, not as identifiers to persist.
- Stop does not restore values. See section 9.
- Set Timescale has no by-name mode, because the runtime API has no per-sequence-name timescale. Retime a specific run through its handle.
- By Index lookups break silently when sequences are reordered. Prefer By Name.
- Play Sequence restarts a running sequence. If that is not what you want, use Play Sequence Unique and choose the behavior explicitly.
- Actions do not create animations. Sequences are authored in the JuiceBox graph editor; this package only drives them.
Where to go next. The Pro quick start covers sequence parameters, handles and the runtime API that these actions are built on. If a sequence behaves unexpectedly, it is usually faster to reproduce it there first and confirm the animation itself is right before looking at the FSM.
