void UActorRecording::StartRecordingActorProperties(ULevelSequence* CurrentSequence, float CurrentSequenceTime) { if(CurrentSequence != nullptr) { // set up our spawnable or possessable for this actor UMovieScene* MovieScene = CurrentSequence->GetMovieScene(); AActor* Actor = GetActorToRecord(); if (bRecordToPossessable) { Guid = MovieScene->AddPossessable(Actor->GetActorLabel(), Actor->GetClass()); CurrentSequence->BindPossessableObject(Guid, *Actor, Actor->GetWorld()); } else { FString TemplateName = GetUniqueSpawnableName(MovieScene, Actor->GetName()); AActor* ObjectTemplate = CastChecked<AActor>(CurrentSequence->MakeSpawnableTemplateFromInstance(*Actor, *TemplateName)); if (ObjectTemplate) { TInlineComponentArray<USkeletalMeshComponent*> SkeletalMeshComponents; ObjectTemplate->GetComponents(SkeletalMeshComponents); for (USkeletalMeshComponent* SkeletalMeshComponent : SkeletalMeshComponents) { SkeletalMeshComponent->SetAnimationMode(EAnimationMode::AnimationSingleNode); SkeletalMeshComponent->bEnableUpdateRateOptimizations = false; SkeletalMeshComponent->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::AlwaysTickPoseAndRefreshBones; SkeletalMeshComponent->ForcedLodModel = 1; } Guid = MovieScene->AddSpawnable(TemplateName, *ObjectTemplate); } } // now add tracks to record if(Guid.IsValid()) { // add our folder FindOrAddFolder(MovieScene); // force set recording to record translations as we need this with no animation UMovieScene3DTransformSectionRecorderSettings* TransformSettings = ActorSettings.GetSettingsObject<UMovieScene3DTransformSectionRecorderSettings>(); check(TransformSettings); TransformSettings->bRecordTransforms = true; // grab components so we can track attachments // don't include non-CDO here as they wont be part of our initial BP (duplicated above) // we will catch these 'extra' components on the first tick const bool bIncludeNonCDO = false; SyncTrackedComponents(bIncludeNonCDO); TInlineComponentArray<USceneComponent*> SceneComponents(GetActorToRecord()); // check if components need recording TInlineComponentArray<USceneComponent*> ValidSceneComponents; for(TWeakObjectPtr<USceneComponent>& SceneComponent : TrackedComponents) { if(ValidComponent(SceneComponent.Get())) { ValidSceneComponents.Add(SceneComponent.Get()); // add all parent components too TArray<USceneComponent*> ParentComponents; SceneComponent->GetParentComponents(ParentComponents); for(USceneComponent* ParentComponent : ParentComponents) { ValidSceneComponents.AddUnique(ParentComponent); } } } ProcessNewComponentArray(ValidSceneComponents); TSharedPtr<FMovieSceneAnimationSectionRecorder> FirstAnimRecorder = nullptr; for(USceneComponent* SceneComponent : ValidSceneComponents) { TSharedPtr<FMovieSceneAnimationSectionRecorder> AnimRecorder = StartRecordingComponentProperties(SceneComponent->GetFName(), SceneComponent, GetActorToRecord(), CurrentSequence, CurrentSequenceTime, AnimationSettings); if(!FirstAnimRecorder.IsValid() && AnimRecorder.IsValid() && GetActorToRecord()->IsA<ACharacter>()) { FirstAnimRecorder = AnimRecorder; } } // we need to create a transform track even if we arent recording transforms if (FSequenceRecorder::Get().GetTransformRecorderFactory().CanRecordObject(GetActorToRecord())) { TSharedPtr<IMovieSceneSectionRecorder> Recorder = FSequenceRecorder::Get().GetTransformRecorderFactory().CreateSectionRecorder(TransformSettings->bRecordTransforms, FirstAnimRecorder); if(Recorder.IsValid()) { Recorder->CreateSection(GetActorToRecord(), MovieScene, Guid, CurrentSequenceTime); Recorder->Record(CurrentSequenceTime); SectionRecorders.Add(Recorder); } } TArray<IMovieSceneSectionRecorderFactory*> ModularFeatures = IModularFeatures::Get().GetModularFeatureImplementations<IMovieSceneSectionRecorderFactory>(MovieSceneSectionRecorderFactoryName); for (IMovieSceneSectionRecorderFactory* Factory : ModularFeatures) { if (Factory->CanRecordObject(GetActorToRecord())) { TSharedPtr<IMovieSceneSectionRecorder> Recorder = Factory->CreateSectionRecorder(ActorSettings); if (Recorder.IsValid()) { Recorder->CreateSection(GetActorToRecord(), MovieScene, Guid, CurrentSequenceTime); Recorder->Record(CurrentSequenceTime); SectionRecorders.Add(Recorder); } } } } } }