Exemple #1
0
FGuid FSequencer::GetHandleToObject( UObject* Object )
{
	TSharedRef<FMovieSceneInstance> FocusedMovieSceneInstance = GetFocusedMovieSceneInstance();
	UMovieScene* FocusedMovieScene = FocusedMovieSceneInstance->GetMovieScene();

	FGuid ObjectGuid = ObjectBindingManager->FindGuidForObject( *FocusedMovieScene, *Object );

	if (ObjectGuid.IsValid())
	{
		// Make sure that the possessable is still valid, if it's not remove the binding so new one 
		// can be created.  This can happen due to undo.
		FMovieScenePossessable* Possessable = FocusedMovieScene->FindPossessable(ObjectGuid);
		if (Possessable == nullptr )
		{
			ObjectBindingManager->UnbindPossessableObjects(ObjectGuid);
			ObjectGuid.Invalidate();
		}
	}
	
	bool bPossessableAdded = false;
	
	// If the object guid was not found attempt to add it
	// Note: Only possessed actors can be added like this
	if( !ObjectGuid.IsValid() && ObjectBindingManager->CanPossessObject( *Object ) )
	{
		// @todo sequencer: Undo doesn't seem to be working at all
		const FScopedTransaction Transaction( LOCTEXT("UndoPossessingObject", "Possess Object with MovieScene") );
		
		// Possess the object!
		{
			// Create a new possessable
			FocusedMovieScene->Modify();

			ObjectGuid = FocusedMovieScene->AddPossessable( Object->GetName(), Object->GetClass() );
			
			if ( IsShotFilteringOn() )
			{
				AddUnfilterableObject(ObjectGuid);
			}
			
			ObjectBindingManager->BindPossessableObject( ObjectGuid, *Object );
			
			bPossessableAdded = true;
		}
	}
	
	if( bPossessableAdded )
	{
		SpawnOrDestroyPuppetObjects( GetFocusedMovieSceneInstance() );
			
		NotifyMovieSceneDataChanged();
	}
	
	return ObjectGuid;
}
Exemple #2
0
void FSequencer::OnActorsDropped( const TArray<TWeakObjectPtr<AActor> >& Actors )
{
	bool bPossessableAdded = false;
	for( TWeakObjectPtr<AActor> WeakActor : Actors )
	{
		AActor* Actor = WeakActor.Get();
		if( Actor != NULL )
		{
			// Grab the MovieScene that is currently focused.  We'll add our Blueprint as an inner of the
			// MovieScene asset.
			UMovieScene* OwnerMovieScene = GetFocusedMovieScene();
			
			// @todo sequencer: Undo doesn't seem to be working at all
			const FScopedTransaction Transaction( LOCTEXT("UndoPossessingObject", "Possess Object with MovieScene") );
			
			// Possess the object!
			{
				// Create a new possessable
				OwnerMovieScene->Modify();
				
				const FGuid PossessableGuid = OwnerMovieScene->AddPossessable( Actor->GetActorLabel(), Actor->GetClass() );
				 
				if ( IsShotFilteringOn() )
				{
					AddUnfilterableObject(PossessableGuid);
				}
				
				ObjectBindingManager->BindPossessableObject( PossessableGuid, *Actor );
				
				bPossessableAdded = true;
			}
		}
	}
	
	if( bPossessableAdded )
	{
		SpawnOrDestroyPuppetObjects( GetFocusedMovieSceneInstance() );
		
		NotifyMovieSceneDataChanged();
	}
}
TSharedPtr<FMovieSceneAnimationSectionRecorder> UActorRecording::StartRecordingComponentProperties(const FName& BindingName, USceneComponent* SceneComponent, UObject* BindingContext, ULevelSequence* CurrentSequence, float CurrentSequenceTime, const FAnimationRecordingSettings& InAnimationSettings)
{
	// first create a possessable for this component to be controlled by
	UMovieScene* OwnerMovieScene = CurrentSequence->GetMovieScene();

	const FGuid PossessableGuid = OwnerMovieScene->AddPossessable(BindingName.ToString(), SceneComponent->GetClass());

	// Set up parent/child guids for possessables within spawnables
	FMovieScenePossessable* ChildPossessable = OwnerMovieScene->FindPossessable(PossessableGuid);
	if (ensure(ChildPossessable))
	{
		ChildPossessable->SetParent(Guid);
	}

	FMovieSceneSpawnable* ParentSpawnable = OwnerMovieScene->FindSpawnable(Guid);
	if (ParentSpawnable)
	{
		ParentSpawnable->AddChildPossessable(PossessableGuid);
	}

	// BindingName must be the component's path relative to its owner Actor
	FLevelSequenceObjectReference ObjectReference(FUniqueObjectGuid(), BindingName.ToString());

	CurrentSequence->BindPossessableObject(PossessableGuid, ObjectReference);

	// First try built-in animation recorder...
	TSharedPtr<FMovieSceneAnimationSectionRecorder> AnimationRecorder = nullptr;
	if (FSequenceRecorder::Get().GetAnimationRecorderFactory().CanRecordObject(SceneComponent))
	{
		AnimationRecorder = FSequenceRecorder::Get().GetAnimationRecorderFactory().CreateSectionRecorder(this, InAnimationSettings);
		AnimationRecorder->CreateSection(SceneComponent, OwnerMovieScene, PossessableGuid, CurrentSequenceTime);
		AnimationRecorder->Record(CurrentSequenceTime);
		SectionRecorders.Add(AnimationRecorder);
	}

	// ...and transform...
	if (FSequenceRecorder::Get().GetTransformRecorderFactory().CanRecordObject(SceneComponent))
	{
		TSharedPtr<IMovieSceneSectionRecorder> Recorder = FSequenceRecorder::Get().GetTransformRecorderFactory().CreateSectionRecorder(true, nullptr);
		if (Recorder.IsValid())
		{
			Recorder->CreateSection(SceneComponent, OwnerMovieScene, PossessableGuid, CurrentSequenceTime);
			Recorder->Record(CurrentSequenceTime);
			SectionRecorders.Add(Recorder);
		}
	}

	// ...now any external recorders
	TArray<IMovieSceneSectionRecorderFactory*> ModularFeatures = IModularFeatures::Get().GetModularFeatureImplementations<IMovieSceneSectionRecorderFactory>(MovieSceneSectionRecorderFactoryName);
	for (IMovieSceneSectionRecorderFactory* Factory : ModularFeatures)
	{
		if (Factory->CanRecordObject(SceneComponent))
		{
			TSharedPtr<IMovieSceneSectionRecorder> Recorder = Factory->CreateSectionRecorder(ActorSettings);
			if (Recorder.IsValid())
			{
				Recorder->CreateSection(SceneComponent, OwnerMovieScene, PossessableGuid, CurrentSequenceTime);
				Recorder->Record(CurrentSequenceTime);
				SectionRecorders.Add(Recorder);
			}
		}
	}

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