JuiceBox / PlayMaker 2 Integration Pro guide → / Asset Store

PlayMaker 2 Integration

Ten actions and two variable types that let any PlayMaker 2 state play, wait for, retime and steer a JuiceBox sequence — with no code and no glue scripts.
Add-on · Requires JuiceBox - PRO and PlayMaker 2

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

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.

ActionWhat it does
Play SequenceStarts a sequence, restarting it if it is already running.
Play Sequence UniqueStarts a sequence with a rule for what to do when it is already running.
Wait For SequenceHolds the rest of the state's actions until a run ends.
Stop SequenceEnds a run, one sequence, or everything on the animation.
Pause SequenceHolds a run in place at the value it had reached.
Resume SequenceRestarts a paused run from where it was held.
Is Sequence RunningSends a true or false event depending on whether something is running.
Get ProgressReads how far a run has advanced, from 0 to 1.
Set TimescaleChanges playback speed. Zero holds; negative runs backwards.
Set ParameterPushes 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:

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:

BehaviorResult
AbortThe new call is dropped. The run already in flight continues undisturbed. This is the default.
OverwriteThe running one is ended and the new call starts from the beginning.
WaitThe 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:

ModeActs on
HandleThe one run the handle names. The Animation field is not needed.
Named SequenceEvery run of that sequence on the animation.
Sequence IndexEvery run of the sequence at that position.
Whole AnimationEvery 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:

TypeTypeTypeType
FloatIntStringVector2
Vector3Vector4QuaternionRect

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.

VariableHolds
Sequence HandleOne live run, as described in section 8. Not serialized.
JuiceBox AnimationA 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

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.