I have recently been working a lot with animation state graphs and discovered some weird behavior. In all my state graphs I start with the idle state going on loop (with a transition from the “start” node). However, in some cases I have had the need to trigger the idle state again at some later stage, so I set up a transition from the “any” node to the idle sate, with the condition trigger “idle”. See picture:
It seems to break the whole animation setup if it is triggered when the idle animation is already playing. This can take the form of consecutive states not to playing properly, or the whole character just freezing up completely.
A quick fix could be something like: if(!this.entity.anim.getTrigger('idle')) this.entity.anim.setTrigger('idle')
However, since the idle animation are playing from the beginning there will be cases when it is playing even if the trigger is not set to true yet, making this fix only work in some cases.
That this setup can break the whole animation graph seems to me like a bug in the engine. Anyone else had this problem? Any suggestions for a better quick fix?
hmm… it might be somewhat related… but the problem is not that the idle animation is interrupted and start playing again from the beginning when you trigger it, which is what is sounds like that issue was about. The trouble is that triggering the initial state when it is already playing actually makes everything else stop working. In the sense that no other animations can be triggered later on.
Ok, so. I set up the project, and got some of the strange behavior. However, I think I might have been somewhat incorrect with my initial assessment. It seems that it doesn’t rly have anything to do with the initial state or “start state”. But rather if you trigger an animation twice, the next new animation you trigger will not play correctly.
Hi @Astra, trigger parameters are consumed when a transition that uses it in one of its conditions is activated. If you set an ‘idle’ trigger while in the Idle state, that trigger will exist until a transition becomes available that can consume it. Checking that the graph isn’t currently in the idle state before setting the idle trigger parameter would stop the graph reentering that state on exit:
if (this.entity.anim.baseLayer.activeState !== 'Idle') this.entity.anim.setTrigger('idle')
If a user pressed a jump key right at the end of the current jump animation, you may want to still queue that user action up. In that case you can use something like:
This way, if the trigger is not consumed in this frame, it gets reset at the end of it.
Also as a side note, I personally prefer to use ‘sub graphs’ over ANY FRAME. With layer.transition , you can transition to any state even if there is no set transition path between the states.
This makes it handy to jump to other parts of the graph.