How do animation state-machine transitions work once compiled?

I’ve been fiddling around with making a more indepth generic graph system just for the hell of it. It’s fun diving around and building custom things. I would like to be able to add my own custom transition graphs much like the Anim BP state machine transitions. I’ve followed the flow pretty well, I think, but I can’t for the life of me figure out what magic sets the boolean value that lets the state continue.

UAnimGraphNode_TransitionResult is the editor class which is the result node and it contains a FAnimNode_TransitionResult from the runtime side of things. This is the struct which contains the bCanEnterTransition UPROPERTY that controls things. I’ve attached a simple 0==0 ? query in a graph and I can observe that during compile bCanEnterTransition is False, but during runtime it does get set to True, but I can’t figure out where this execution happens. AnimBP does some internal hoohaa to build the EdGraph that sits in the transition node but it doesn’t look like much happens to it. At some point the entire package ends up in an UAnimBlueprintGeneratedClass but at that point there’s nothing that I can recognize anymore. The UAnimBlueprintGeneratedClass contains a set of “Baked state machines” which do have “transitions” equal to the number of ones that I put in the blueprint, but these baked transition structures just contain a series of ints and a few other variables and nothing else that I can tie to the original graph used.

I am missing some piece to the puzzle somewhere and while it might be a long shot asking the internet I thought I’d give it a go on here! x)

Anim node property inputs get set with these calls in the node’s Update_AnyThread:


Node->GetEvaluateGraphExposedInputs().Execute(Context);

Basically a BP graph evaluation finding the value of each input pin on the node. After that call, the UProperties have their updated values.

In FAnimNode_TransitionResult’s case, that doesn’t seem to be done in the node’s implementation (there’s really nothing there). I think it’s the calls in FAnimNode_StateMachine’s FindValidTransition which actually do the “magic”, I’ve clipped the relevant code below


if (FAnimNode_TransitionResult* StateEntryRuleNode = GetNodeFromPropertyIndex<FAnimNode_TransitionResult>(Context.AnimInstanceProxy->GetAnimInstanceObject(), AnimBlueprintClass, StateInfo.EntryRuleNodeIndex))
{
  // Execute it and see if we can take this rule
  StateEntryRuleNode->GetEvaluateGraphExposedInputs().Execute(Context);
  // not ok, back out
  if (!StateEntryRuleNode->bCanEnterTransition)
  {
    return false;
  }
}