void FAnimNode_StateMachine::SetState(const FAnimationBaseContext& Context, int32 NewStateIndex) { if (NewStateIndex != CurrentState) { const int32 PrevStateIndex = CurrentState; if(CurrentState != INDEX_NONE && CurrentState < OnGraphStatesExited.Num()) { OnGraphStatesExited[CurrentState].ExecuteIfBound(*this, CurrentState, NewStateIndex); } // Determine if the new state is active or not const bool bAlreadyActive = GetStateWeight(NewStateIndex) > 0.0f; SetStateInternal(NewStateIndex); if (!bAlreadyActive && !IsAConduitState(NewStateIndex)) { // Initialize the new state since it's not part of an active transition (and thus not still initialized) FAnimationInitializeContext InitContext(Context.AnimInstance); StatePoseLinks[NewStateIndex].Initialize(InitContext); // Also update BoneCaching. FAnimationCacheBonesContext CacheBoneContext(Context.AnimInstance); StatePoseLinks[NewStateIndex].CacheBones(CacheBoneContext); } if(CurrentState != INDEX_NONE && CurrentState < OnGraphStatesEntered.Num()) { OnGraphStatesEntered[CurrentState].ExecuteIfBound(*this, PrevStateIndex, CurrentState); } } }
void FAnimNode_StateMachine::ConditionallyCacheBonesForState(int32 StateIndex, FAnimationBaseContext Context) { // Only call CacheBones when needed. check(StateCacheBoneCounters.IsValidIndex(StateIndex)); if (!StateCacheBoneCounters[StateIndex].IsSynchronizedWith(Context.AnimInstanceProxy->GetCachedBonesCounter())) { // keep track of states that have had CacheBones called on. StateCacheBoneCounters[StateIndex].SynchronizeWith(Context.AnimInstanceProxy->GetCachedBonesCounter()); FAnimationCacheBonesContext CacheBoneContext(Context.AnimInstanceProxy); StatePoseLinks[StateIndex].CacheBones(CacheBoneContext); } }