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; }
void FSequencer::FocusSubMovieScene( TSharedRef<FMovieSceneInstance> SubMovieSceneInstance ) { // Check for infinite recursion check( SubMovieSceneInstance != MovieSceneStack.Top() ); // Focus the movie scene MovieSceneStack.Push( SubMovieSceneInstance ); // Reset data that is only used for the previous movie scene ResetPerMovieSceneData(); // Update internal data for the new movie scene NotifyMovieSceneDataChanged(); }
void FSequencer::PopToMovieScene( TSharedRef<FMovieSceneInstance> SubMovieSceneInstance ) { if( MovieSceneStack.Num() > 1 ) { // Pop until we find the movie scene to focus while( SubMovieSceneInstance != MovieSceneStack.Last() ) { MovieSceneStack.Pop(); } check( MovieSceneStack.Num() > 0 ); ResetPerMovieSceneData(); NotifyMovieSceneDataChanged(); } }
void FMaterialTrackEditor::AddVectorParameter( FGuid ObjectBinding, UMovieSceneMaterialTrack* MaterialTrack, FName ParameterName ) { UMovieSceneSequence* MovieSceneSequence = GetMovieSceneSequence(); float KeyTime = GetTimeForKey( MovieSceneSequence ); UMaterial* Material = GetMaterialForTrack( ObjectBinding, MaterialTrack ); if ( Material != nullptr ) { const FScopedTransaction Transaction( LOCTEXT( "AddVectorParameter", "Add vector parameter" ) ); FLinearColor ParameterValue; Material->GetVectorParameterValue( ParameterName, ParameterValue ); MaterialTrack->Modify(); for ( UMovieSceneSection* Section : MaterialTrack->GetAllSections() ) { Section->Modify(); } MaterialTrack->AddVectorParameterKey( ParameterName, KeyTime, ParameterValue ); } NotifyMovieSceneDataChanged(); }
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(); } }
void FSequencer::ResetToNewRootMovieScene( UMovieScene& NewRoot, TSharedRef<ISequencerObjectBindingManager> NewObjectBindingManager ) { DestroySpawnablesForAllMovieScenes(); //@todo Sequencer - Encapsulate this better MovieSceneStack.Empty(); Selection.Empty(); FilteringShots.Empty(); UnfilterableSections.Empty(); UnfilterableObjects.Empty(); MovieSceneSectionToInstanceMap.Empty(); NewRoot.SetFlags(RF_Transactional); ObjectBindingManager = NewObjectBindingManager; // Focusing the initial movie scene needs to be done before the first time GetFocusedMovieSceneInstane or GetRootMovieSceneInstance is used RootMovieSceneInstance = MakeShareable(new FMovieSceneInstance(NewRoot)); MovieSceneStack.Add(RootMovieSceneInstance.ToSharedRef()); SequencerWidget->ResetBreadcrumbs(); NotifyMovieSceneDataChanged(); }
void FSpawnTrackEditor::HandleAddSpawnTrackMenuEntryExecute(FGuid ObjectBinding) { FScopedTransaction AddSpawnTrackTransaction(LOCTEXT("AddSpawnTrack_Transaction", "Add Spawn Track")); AddTrack(GetSequencer()->GetFocusedMovieSceneSequence()->GetMovieScene(), ObjectBinding, UMovieSceneSpawnTrack::StaticClass(), NAME_None); NotifyMovieSceneDataChanged(); }
void FSequencer::InitSequencer( const FSequencerInitParams& InitParams, const TArray<FOnCreateTrackEditor>& TrackEditorDelegates ) { if( IsSequencerEnabled() ) { bIsEditingWithinLevelEditor = InitParams.bEditWithinLevelEditor; ToolkitHost = InitParams.ToolkitHost; LastViewRange = InitParams.ViewParams.InitalViewRange; ScrubPosition = InitParams.ViewParams.InitialScrubPosition; ObjectChangeListener = InitParams.ObjectChangeListener; ObjectBindingManager = InitParams.ObjectBindingManager; check( ObjectChangeListener.IsValid() ); check( ObjectBindingManager.IsValid() ); UMovieScene& RootMovieScene = *InitParams.RootMovieScene; RootMovieScene.SetFlags( RF_Transactional ); // Focusing the initial movie scene needs to be done before the first time GetFocusedMovieSceneInstane or GetRootMovieSceneInstance is used RootMovieSceneInstance = MakeShareable( new FMovieSceneInstance( RootMovieScene ) ); MovieSceneStack.Add( RootMovieSceneInstance.ToSharedRef() ); // Make internal widgets SequencerWidget = SNew( SSequencer, SharedThis( this ) ) .ViewRange( this, &FSequencer::OnGetViewRange ) .ScrubPosition( this, &FSequencer::OnGetScrubPosition ) .OnScrubPositionChanged( this, &FSequencer::OnScrubPositionChanged ) .OnViewRangeChanged( this, &FSequencer::OnViewRangeChanged, false ); // When undo occurs, get a notification so we can make sure our view is up to date GEditor->RegisterForUndo(this); if( bIsEditingWithinLevelEditor ) { // @todo remove when world-centric mode is added // Hook into the editor's mechanism for checking whether we need live capture of PIE/SIE actor state GEditor->GetActorRecordingState().AddSP(this, &FSequencer::GetActorRecordingState); } // Create tools and bind them to this sequencer for( int32 DelegateIndex = 0; DelegateIndex < TrackEditorDelegates.Num(); ++DelegateIndex ) { check( TrackEditorDelegates[DelegateIndex].IsBound() ); // Tools may exist in other modules, call a delegate that will create one for us TSharedRef<FMovieSceneTrackEditor> TrackEditor = TrackEditorDelegates[DelegateIndex].Execute( SharedThis( this ) ); // Keep track of certain editors if ( TrackEditor->SupportsType( UMovieSceneDirectorTrack::StaticClass() ) ) { DirectorTrackEditor = TrackEditor; } else if ( TrackEditor->SupportsType( UMovieSceneAnimationTrack::StaticClass() ) ) { AnimationTrackEditor = TrackEditor; } TrackEditors.Add( TrackEditor ); } ZoomAnimation = FCurveSequence(); ZoomCurve = ZoomAnimation.AddCurve(0.f, 0.35f, ECurveEaseFunction::QuadIn); OverlayAnimation = FCurveSequence(); OverlayCurve = OverlayAnimation.AddCurve(0.f, 0.35f, ECurveEaseFunction::QuadIn); // Update initial movie scene data NotifyMovieSceneDataChanged(); // NOTE: Could fill in asset editor commands here! BindSequencerCommands(); } }
void FSequencer::PostUndo(bool bSuccess) { NotifyMovieSceneDataChanged(); }
void FSequencer::OnRequestNodeDeleted( TSharedRef<const FSequencerDisplayNode>& NodeToBeDeleted ) { bool bAnySpawnablesRemoved = false; bool bAnythingRemoved = false; TSharedRef<FMovieSceneInstance> MovieSceneInstance = GetFocusedMovieSceneInstance(); UMovieScene* OwnerMovieScene = MovieSceneInstance->GetMovieScene(); // Only object nodes or section areas can be deleted if( NodeToBeDeleted->GetType() == ESequencerNode::Object ) { OwnerMovieScene->SetFlags( RF_Transactional ); const FGuid& BindingToRemove = StaticCastSharedRef<const FObjectBindingNode>( NodeToBeDeleted )->GetObjectBinding(); //@todo Sequencer - add transaction // Try to remove as a spawnable first bool bRemoved = OwnerMovieScene->RemoveSpawnable( BindingToRemove ); if( bRemoved ) { bAnySpawnablesRemoved = true; } if( !bRemoved ) { // The guid should be associated with a possessable if it wasnt a spawnable bRemoved = OwnerMovieScene->RemovePossessable( BindingToRemove ); // @todo Sequencer - undo needs to work here ObjectBindingManager->UnbindPossessableObjects( BindingToRemove ); // If this check fails the guid was not associated with a spawnable or possessable so there was an invalid guid being stored on a node check( bRemoved ); } bAnythingRemoved = true; } else if( NodeToBeDeleted->GetType() == ESequencerNode::Track ) { TSharedRef<const FTrackNode> SectionAreaNode = StaticCastSharedRef<const FTrackNode>( NodeToBeDeleted ); UMovieSceneTrack* Track = SectionAreaNode->GetTrack(); UMovieScene* FocusedMovieScene = GetFocusedMovieScene(); FocusedMovieScene->SetFlags( RF_Transactional ); if( FocusedMovieScene->IsAMasterTrack( Track ) ) { FocusedMovieScene->RemoveMasterTrack( Track ); } else { FocusedMovieScene->RemoveTrack( Track ); } bAnythingRemoved = true; } if( bAnythingRemoved ) { if( bAnySpawnablesRemoved ) { // @todo Sequencer Sub-MovieScenes needs to destroy objects for all movie scenes that had this node SpawnOrDestroyPuppetObjects( MovieSceneInstance ); } NotifyMovieSceneDataChanged(); } }