void FMatineeImportTools::CopyInterpParticleTrack( TSharedRef<ISequencer> Sequencer, UInterpTrackToggle* MatineeToggleTrack, UMovieSceneParticleTrack* ParticleTrack ) { const FScopedTransaction Transaction( NSLOCTEXT( "Sequencer", "PasteMatineeParticleTrack", "Paste Matinee particle track" ) ); bool bSectionCreated = false; ParticleTrack->Modify(); float KeyTime = MatineeToggleTrack->GetKeyframeTime( 0 ); UMovieSceneParticleSection* Section = Cast<UMovieSceneParticleSection>( MovieSceneHelpers::FindSectionAtTime( ParticleTrack->GetAllSections(), KeyTime ) ); if ( Section == nullptr ) { Section = Cast<UMovieSceneParticleSection>( ParticleTrack->CreateNewSection() ); ParticleTrack->AddSection( *Section ); bSectionCreated = true; } if (Section->TryModify()) { float SectionMin = Section->GetStartTime(); float SectionMax = Section->GetEndTime(); FIntegralCurve& ParticleCurve = Section->GetParticleCurve(); for ( const auto& Key : MatineeToggleTrack->ToggleTrack ) { EParticleKey::Type ParticleKey; if ( TryConvertMatineeToggleToOutParticleKey( Key.ToggleAction, ParticleKey ) ) { ParticleCurve.AddKey( Key.Time, (int32)ParticleKey, ParticleCurve.FindKey( Key.Time ) ); } SectionMin = FMath::Min( SectionMin, Key.Time ); SectionMax = FMath::Max( SectionMax, Key.Time ); } Section->SetStartTime( SectionMin ); Section->SetEndTime( SectionMax ); if ( bSectionCreated ) { Sequencer->NotifyMovieSceneDataChanged(); } } }
void FMovieSceneParticleTrackInstance::Update( float Position, float LastPosition, const TArray<UObject*>& RuntimeObjects, class IMovieScenePlayer& Player ) { // @todo Sequencer We need something analagous to Matinee 1's particle replay tracks // What we have here is simple toggling/triggering if (Position > LastPosition && Player.GetPlaybackStatus() == EMovieScenePlayerStatus::Playing) { bool bTrigger = false, bOn = false, bOff = false; const TArray<UMovieSceneSection*> Sections = ParticleTrack->GetAllParticleSections(); for (int32 i = 0; i < Sections.Num(); ++i) { UMovieSceneParticleSection* Section = Cast<UMovieSceneParticleSection>(Sections[i]); if (Section->GetKeyType() == EParticleKey::Trigger) { if (Position > Section->GetStartTime() && LastPosition < Section->GetStartTime()) { bTrigger = true; } } else if (Section->GetKeyType() == EParticleKey::Toggle) { if (Position >= Section->GetStartTime() && Position <= Section->GetEndTime()) { bOn = true; } else if (Position >= Section->GetEndTime() && LastPosition < Section->GetEndTime()) { bOff = true; } } } if (bTrigger || bOn || bOff) { for (int32 i = 0; i < RuntimeObjects.Num(); ++i) { AEmitter* Emitter = Cast<AEmitter>(RuntimeObjects[i]); if (Emitter) { if (bTrigger) { Emitter->ToggleActive(); } else if (bOn) { Emitter->Activate(); } else if (bOff) { Emitter->Deactivate(); } } } } } else { for (int32 i = 0; i < RuntimeObjects.Num(); ++i) { AEmitter* Emitter = Cast<AEmitter>(RuntimeObjects[i]); if (Emitter) { Emitter->Deactivate(); } } } }