// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2020. #include "FMODEventParameterTrackEditor.h" #include "FMODAmbientSound.h" #include "FMODEvent.h" #include "FMODStudioModule.h" #include "Framework/MultiBox/MultiBoxBuilder.h" #include "Sequencer/FMODEventParameterTrack.h" #include "Sections/MovieSceneParameterSection.h" #include "Sequencer/FMODParameterSection.h" #include "SequencerUtilities.h" #include "fmod_studio.hpp" #define LOCTEXT_NAMESPACE "FMODEeventParameterTrackEditor" FName FFMODEventParameterTrackEditor::TrackName("FMODEventParameter"); FFMODEventParameterTrackEditor::FFMODEventParameterTrackEditor(TSharedRef InSequencer) : FMovieSceneTrackEditor(InSequencer) { } TSharedRef FFMODEventParameterTrackEditor::CreateTrackEditor(TSharedRef OwningSequencer) { return MakeShareable(new FFMODEventParameterTrackEditor(OwningSequencer)); } TSharedRef FFMODEventParameterTrackEditor::MakeSectionInterface( UMovieSceneSection &SectionObject, UMovieSceneTrack &Track, FGuid ObjectBinding) { UMovieSceneParameterSection *ParameterSection = Cast(&SectionObject); checkf(ParameterSection != nullptr, TEXT("Unsupported section type.")); return MakeShareable(new FFMODParameterSection(*ParameterSection)); } TSharedPtr FFMODEventParameterTrackEditor::BuildOutlinerEditWidget( const FGuid &ObjectBinding, UMovieSceneTrack *Track, const FBuildEditWidgetParams &Params) { UFMODEventParameterTrack *EventParameterTrack = Cast(Track); // Create a container edit box return FSequencerUtilities::MakeAddButton(LOCTEXT("ParameterText", "Parameter"), FOnGetContent::CreateSP(this, &FFMODEventParameterTrackEditor::OnGetAddParameterMenuContent, ObjectBinding, EventParameterTrack), Params.NodeIsHovered, GetSequencer()); } void FFMODEventParameterTrackEditor::BuildObjectBindingTrackMenu(FMenuBuilder &MenuBuilder, const TArray &ObjectBindings, const UClass *ObjectClass) { if (ObjectClass->IsChildOf(AFMODAmbientSound::StaticClass()) || ObjectClass->IsChildOf(UFMODAudioComponent::StaticClass())) { const TSharedPtr ParentSequencer = GetSequencer(); MenuBuilder.AddMenuEntry(LOCTEXT("AddFMODParameterTrack", "FMOD Event Parameter Track"), LOCTEXT("AddFMODParameterTrackTooltip", "Adds a track for controlling FMOD event parameter values."), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &FFMODEventParameterTrackEditor::AddEventParameterTrack, ObjectBindings[0]), FCanExecuteAction::CreateSP(this, &FFMODEventParameterTrackEditor::CanAddEventParameterTrack, ObjectBindings[0]))); } } bool FFMODEventParameterTrackEditor::SupportsType(TSubclassOf Type) const { return Type == UFMODEventParameterTrack::StaticClass(); } TSharedRef FFMODEventParameterTrackEditor::OnGetAddParameterMenuContent(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack) { TSharedPtr SequencerPtr = GetSequencer(); AFMODAmbientSound *Sound = SequencerPtr.IsValid() ? Cast(SequencerPtr->FindSpawnedObjectOrTemplate(ObjectBinding)) : nullptr; UFMODAudioComponent *AudioComponent; if (IsValid(Sound)) { AudioComponent = Sound->AudioComponent; } else { AudioComponent = SequencerPtr.IsValid() ? Cast(SequencerPtr->FindSpawnedObjectOrTemplate(ObjectBinding)) : nullptr; } return BuildParameterMenu(ObjectBinding, EventParameterTrack, AudioComponent); } TSharedRef FFMODEventParameterTrackEditor::BuildParameterMenu( FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack, UFMODAudioComponent *AudioComponent) { FMenuBuilder AddParameterMenuBuilder(true, nullptr); if (IsValid(AudioComponent) && AudioComponent->Event.IsValid()) { TArray ParameterNamesAndActions; TArray ParameterDescriptions; AudioComponent->Event->GetParameterDescriptions(ParameterDescriptions); for (FMOD_STUDIO_PARAMETER_DESCRIPTION &ParameterDescription : ParameterDescriptions) { FName ParameterName(ParameterDescription.name); FExecuteAction InitAction = FExecuteAction::CreateSP(this, &FFMODEventParameterTrackEditor::AddParameter, ObjectBinding, EventParameterTrack, ParameterName); FUIAction AddParameterMenuAction(InitAction); FParameterNameAndAction NameAndAction(ParameterName, AddParameterMenuAction); ParameterNamesAndActions.Add(NameAndAction); } // Sort and generate menu. ParameterNamesAndActions.Sort(); for (FParameterNameAndAction NameAndAction : ParameterNamesAndActions) { AddParameterMenuBuilder.AddMenuEntry(FText::FromName(NameAndAction.ParameterName), FText(), FSlateIcon(), NameAndAction.Action); } } return AddParameterMenuBuilder.MakeWidget(); } bool FFMODEventParameterTrackEditor::CanAddEventParameterTrack(FGuid ObjectBinding) { return GetSequencer()->GetFocusedMovieSceneSequence()->GetMovieScene()->FindTrack( UFMODEventParameterTrack::StaticClass(), ObjectBinding, TrackName) == nullptr; } void FFMODEventParameterTrackEditor::AddEventParameterTrack(FGuid ObjectBinding) { FindOrCreateTrackForObject(ObjectBinding, UFMODEventParameterTrack::StaticClass(), TrackName, true); GetSequencer()->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::MovieSceneStructureItemAdded); } void FFMODEventParameterTrackEditor::AddParameter(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack, FName ParameterName) { UMovieSceneSequence *MovieSceneSequence = GetMovieSceneSequence(); FFrameNumber KeyTime = GetTimeForKey(); for (TWeakObjectPtr<> Object : GetSequencer()->FindObjectsInCurrentSequence(ObjectBinding)) { AFMODAmbientSound *Sound = Cast(Object.Get()); UFMODAudioComponent *AudioComponent = nullptr; if (IsValid(Sound)) { AudioComponent = Sound->AudioComponent; } else { AudioComponent = Cast(Object.Get()); } if (IsValid(AudioComponent)) { float Value = AudioComponent->GetParameter(ParameterName); const FScopedTransaction Transaction(LOCTEXT("AddEventParameter", "Add event parameter")); EventParameterTrack->Modify(); EventParameterTrack->AddParameterKey(ParameterName, KeyTime, Value); } } GetSequencer()->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::MovieSceneStructureItemAdded); } #undef LOCTEXT_NAMESPACE