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);
	}
}