void FFaceFXAnimationTrackInstance::RestoreState(const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance)
{
	for (int32 i = 0; i < RuntimeObjects.Num(); ++i)
	{
		UObject* RuntimeObject = RuntimeObjects[i].Get();
		UFaceFXComponent* FaceFXComponent = GetFaceFXComponent(RuntimeObject);
		if (!FaceFXComponent)
		{
			continue;
		}

		FaceFXComponent->StopAll();

		TArray<USkeletalMeshComponent*> SkelMeshTargets;
		FaceFXComponent->GetSetupSkelMeshComponents(SkelMeshTargets);
		for (USkeletalMeshComponent* SkelMeshTarget : SkelMeshTargets)
		{
			if (SkelMeshTarget->GetAnimationMode() == EAnimationMode::Type::AnimationBlueprint)
			{
				if (UAnimInstance* AnimInstance = SkelMeshTarget->GetAnimInstance())
				{
					AnimInstance->Montage_Stop(0.f);
					AnimInstance->UpdateAnimation(0.f, false);
				}

				// Update space bases to reset it back to ref pose
				SkelMeshTarget->RefreshBoneTransforms();
				SkelMeshTarget->RefreshSlaveComponents();
				SkelMeshTarget->UpdateComponentToWorld();
			}
		}
	}
}
/** Stops the playback of any animation of all FaceFX components of the given runtime objects */
void StopAllPlayback(const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects)
{
	for (int32 i = 0; i < RuntimeObjects.Num(); ++i)
	{
		UObject* RuntimeObject = RuntimeObjects[i].Get();
		UFaceFXComponent* FaceFXComponent = GetFaceFXComponent(RuntimeObject);
		if (!FaceFXComponent)
		{
			continue;
		}

		FaceFXComponent->StopAll();

		//enforce an update on the bones to trigger blend nodes
		TArray<USkeletalMeshComponent*> SkelMeshTargets;
		FaceFXComponent->GetSetupSkelMeshComponents(SkelMeshTargets);
		for (USkeletalMeshComponent* SkelMeshTarget : SkelMeshTargets)
		{
			SkelMeshTarget->RefreshBoneTransforms();
		}
	}
}