Is it okay for an animation to drive state changes?

Programmer here with no idea about animation, so bear with me. Take this simple (contrived) anim state machine:

Idle <-> DoingSomething

The Idle -> DoingSomething transition triggers when a bWantsToDoSomething variable is set by the controlling character logic.

I want the DoingSomething -> Idle return transition to trigger when the DoingSomething animation has completed. I set this up, and also add a notify to its StartTransition event, in which I report back to the movement controller, which resets bWantsToDoSomething to false.

This doesn’t work - the transition back to Idle is followed immediately by a transition straight back to DoingSomething again. I finally discovered that this is because all potential transitions are evaluated recursively at the start of an update, and the notify events are held back and fired all together at the end of the update. So having transitioned to Idle but with the notify not yet processed, bWantsToDoSomething is still true, and it immediately takes the transition back out again.

The upshot is, you can’t reliably use state machine notifies to change variables which are used in transition conditions. This seems like a surprising limitation to me. Am I going about things in entirely the wrong way?

Well what you are talking about revolves more around design theory than what would be consider best practice as to migration of required animations for a given event so as part of the design what works best is based on the level of complexity of the animations that needs to be triggered for a given event.

So from a programmer perspective I doubt that changing a function, which at it’s basic level is what a state machine is, is ideal in any given situation that also compounds latency problems by including arguments as to when a state can change from one state to another.

With this kind of set up the animation migration would then be.

Enter the state machine based on an event generated by the event graph. Change from one event to another based on a change on the exit argument contained with in the event with in the state machine. The problem with this type of migration is the requirements of an argument must be meet if the requirement for the animation is to exit full from the current state machine to enter into another.

Bottom line is state machines are not very data driven friendly where the action of a given animation event should directly correspond to an event being triggered by the player by pressing a button or driven by mouse input or any other device as being pure data with out the need for evaluation with in the animgraph.

Long way of saying best practice with in a complex animation design system is to keep state changes that are needed in the event graph and keep all arguments as to event changes out of the animgraph.

To explain a bit more here is something I did way back as to design theory.

@FrankieV: Thanks for the explanation. What you say makes sense, I did immediately feel like this was perhaps something I just shouldn’t be doing. I’m just not sure what the recommended approach would be though.

Say I have a character standing in front of a wall. When the player presses a button, I want the character to climb up the wall onto the top ledge. The climbing animation is a one-off animation, from standing back to standing. How should I go about having that animation play, and have control returned to the player when it completes, if not via an anim notify triggered by the end of the animation?

I could just tell the movement controller to ignore player input for a fixed amount of time, which I’d have to manually sync with the length of the animation, but that doesn’t seem like a good solution. Should I perhaps be using root motion, and then have the movement controller detect that the climbing has completed by continually checking the character’s position?

I feel like I must be missing something fairly obvious here.