Transitions

Transitions are what connect states to determine when the active state should switch.

Creating a Transition

To create a transition, right-click the source state and select Make Transition. Then, click on the destination state.

You can also end the transition at an empty space in the graph to create a new state automatically:

As a shortcut, you can hold Ctrl (Cmd on Mac) on the source node and drag to create a transition.

Editing a Transition

Just like flow states, a transition is also... a nested flow graph!


As you can see in the graph inspector, there are a few problems with our new transition. It is never traversed because we never provided an event specifying when to branch. This is why the transition, along with the destination state, are both dimmed out.

If you double-click its node or click the Edit Graph button, you will dig into the transition's graph. By default, it is configured like this:


The Trigger State Transition unit is a special unit that tells the parent state it should branch via the current transition. You can use any unit in a state transition graph, like events or branches.

For example, if we want to transition to the chase state only when an object with the Player tag enters the trigger on the enemy, we could have a transition graph that looks like this:


Finally, if we want to customize the label our transition will have in the parent state graph, we can deselect all units and edit the graph's title in the graph inspector:


When we go back to the parent state, our transition looks like so:


If you don't assign a custom title for your transition, the name and description of the event will be used.

By default, transition labels are always visible. If you find this takes up too much screen real-estate in your graph, you can change their display trigger under Preferences > Bolt > State Graphs > Transitions Reveal.


Self Transitions

Sometimes, it might be useful for a state to transition to itself. To do so, right-click the state and choose Make Self Transition

For example, imagine you want an enemy to patrol by changing its destination to a random position every 3 seconds. 

Your patrol state's flow graph could be:



And your self-transition's flow graph could be

In the parent state graph, it would look like:

Multiple Transitions

There is no limit to how many transitions can be added to a state. However, there is no notion of priority between transitions. You have to use conditions to make sure the right transition gets chosen.

This article was helpful for 22 people. Is this article helpful for you?

What happens if two transitions of the currently active state are fulfilled at the exact same time?

There is no notion of priority between transitions, so if two or more conditions are triggered in the same frame, which one will get picked is undefined (unpredictable).

I see, so in this case how do I have to imagine what would happen within the state machine? Is it like the current state gets chosen randomly between our two options or will there be runtime errors or something?

Besides that, why don't you "just" add transition priorities to the FSMs? Don't get me wrong, I know that such scenarios as they've been discussed here are pretty rare. However, regarding the fact that when using FSMs one of the most important aspects (if not the most) is to avoid undefined states, I would consider a way to deal with this a core functionality. Sorry for sounding overly strict right now, actually I'm just curious about why no such feature exists. =)

+3

Not "randomly", but "unpredictably"; it depends on a lot of factors like the order in which the graph elements were deserialized, etc. You should not rely on a transition always happening before another.

As to why I'm not "just" adding it in, it's because it would be an entire redesign of how transitions work. Right now, they are event-based, not condition-based. A priority approach requires condition-based transitions that are checked one after the other, on every update or fixed update. This has the advantage of easy prioritizing, yes, but it loses all the flexibility of listening to any kind of event inside the transition graphs. 

To have both events and priorization, each event in each transition would need to be aware of all other transition's events (recursively!) to order their triggering at every frame. This would be extremely performance intensive.

It's usually easier than it seems to create "non-ambiguous" transitions that do not require priorization to work!