- Home /
The question is answered, right answer was accepted
Mecanim "trigger" parameter behaviour with multiple animator layers
Hi, everybody.
I've noticed a strange behaviour of mecanim's "trigger" animator parameter.
Let's say I have an animator controller with multiple layers and a trigger parameter defined in this controller. This trigger is used to perform transitions on different layers. Moreover, this transitions can and should be performed simultaneously. E.g. when setting "walk" trigger character should stop suffering animation (which is on the layer with index, 2) and start walking (layer with index 1). So the problem is: transition on higher layer (i.e. with higher index) can never be fired. If the transition on lower layer is performed too fast, the trigger will be reset before higher layer even start its transition. This can happen if Time.timeScale value is big (I reproduced with timeScale equals 3), or if you set some triggers right after another.
I've implemented some sort of triggers queue to handle this strange behaviour in case of multiple triggers set one after another. But cannot think up anything to fight with timeScale.
Actually, I think, that some kind of triggers queue (synchronized with multiple layers) should be implemented internaly in Mecanim, it would be a much more intuitive for usage.
So the first question is: Why Unity implemented such behavoiur of triggers?
The second one: Any suggestions how to cope with timeScale issue.
This is definitely strange. I assumed that every active state in every layer was informed about each trigger fired.
How to fix this? Well, I tend to stick to bools rather than triggers anyways, and they won't suffer from this problem. So that's my suggestion - build your system around booleans.
The reason for why I'm already doing this is that with triggers, I kept introducing bugs related to ti$$anonymous$$g, where triggers were not consumed when I sent them, and idled in the system until I passed by a state that could consume that trigger. Your issue gives me another reason for why I'll do this.
Not posting this as an answer as it's not really an answer, it's a work around.
I've though up couple of workarounds for this.
The first, which I liked more, is hand-made triggers system (as you suggested). But this is quite hard task, if you want to make maintainable module (and actually I don't have enough time for this right now). This solution, nevertheless, can solve the problem completely.
The second solution: duplicate triggers and make connected set of triggers (fast but hard to maintain for big animator controllers).
And the third one (which I ended up with): setup transitions more precisely. It fixes my problem but it's not universal.
Answer by JustMax · Jan 19, 2015 at 02:09 PM
http://unity3d.com/unity/whats-new/unity-4.5.5
Here is said: "Mecanim: Fixed trigger parameter consumption when used by multiple layers."
I'm pretty sure that the issue i've described is already fixed in Unity version over 4.5.5.
The problem persists (or is back) in Unity 5.4
The trigger is 'consumed' when used by the first layer.
Just in case someone stumbles over this thread while searching for an answer. After a while I managed to figure out how to get trigger parameters to work on multiple layers in Unity 2017.1. So yeah, triggers do work on multiple layers but the gotcha is this:
Let's say that we have Base layer, layer A and layer B and a trigger parameter $$anonymous$$rX. All of them have a transition that will be triggered by $$anonymous$$rX and on the Base and A layer the transition doesn't have exit time but on layer B the transition has an exit time. In this scenario, the transition would be successfully performed on the layers Base and A, but not on B, because when the statemachine on layer B evaluates transition conditions, it will have missed the trigger due to exit time.
Hopefully this clears up. And this is just something that seemed to be the case when I was playing around and testing it, so don't treat this as the absolute truth :D
None of my transitions have an exit time and sometimes the trigger is "consumed" by one layer, sometimes by another, I did not find any pattern for this, unfortunately.