fixed issue

This commit is contained in:
Ji Yoon Rhee
2024-02-10 17:06:19 -05:00
parent b045551102
commit 2c8481bd61
647 changed files with 97393 additions and 6970 deletions

View File

@ -0,0 +1,185 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#include "Sequencer/FMODChannelEditors.h"
#include "ISequencerChannelInterface.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Widgets/SCompoundWidget.h"
#include "MovieSceneTimeHelpers.h"
#include "MovieSceneToolHelpers.h"
#include "ScopedTransaction.h"
#include "EditorWidgets/Public/SEnumCombo.h"
#include "EditorStyleSet.h"
#include "Channels/MovieSceneChannelTraits.h"
class SFMODEventControlKeyEditor : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SFMODEventControlKeyEditor) {}
SLATE_END_ARGS();
void Construct(const FArguments &InArgs, TMovieSceneChannelHandle<FFMODEventControlChannel> InChannelHandle,
TWeakObjectPtr<UMovieSceneSection> InWeakSection, TWeakPtr<ISequencer> InWeakSequencer, UEnum *InEnum)
{
ChannelHandle = InChannelHandle;
WeakSection = InWeakSection;
WeakSequencer = InWeakSequencer;
ChildSlot[MovieSceneToolHelpers::MakeEnumComboBox(InEnum,
TAttribute<int32>::Create(TAttribute<int32>::FGetter::CreateSP(this, &SFMODEventControlKeyEditor::OnGetCurrentValueAsInt)),
SEnumComboBox::FOnEnumSelectionChanged::CreateSP(this, &SFMODEventControlKeyEditor::OnChangeKey))];
}
private:
int32 OnGetCurrentValueAsInt() const
{
using namespace UE::MovieScene;
FFMODEventControlChannel *Channel = ChannelHandle.Get();
ISequencer *Sequencer = WeakSequencer.Pin().Get();
UMovieSceneSection *OwningSection = WeakSection.Get();
uint8 Result = 0;
if (Channel && Sequencer && OwningSection)
{
const FFrameTime CurrentTime = UE::MovieScene::ClampToDiscreteRange(Sequencer->GetLocalTime().Time, OwningSection->GetRange());
EvaluateChannel(Channel, CurrentTime, Result);
}
return Result;
}
void SetValue(uint8 InValue)
{
using namespace UE::MovieScene;
UMovieSceneSection *OwningSection = WeakSection.Get();
if (!OwningSection)
{
return;
}
OwningSection->SetFlags(RF_Transactional);
FFMODEventControlChannel *Channel = ChannelHandle.Get();
ISequencer *Sequencer = WeakSequencer.Pin().Get();
if (!OwningSection->TryModify() || !Channel || !Sequencer)
{
return;
}
const FFrameNumber CurrentTime = Sequencer->GetLocalTime().Time.FloorToFrame();
const bool bAutoSetTrackDefaults = Sequencer->GetAutoSetTrackDefaults();
EMovieSceneKeyInterpolation Interpolation = Sequencer->GetKeyInterpolation();
TArray<FKeyHandle> KeysAtCurrentTime;
Channel->GetKeys(TRange<FFrameNumber>(CurrentTime), nullptr, &KeysAtCurrentTime);
if (KeysAtCurrentTime.Num() > 0)
{
AssignValue(Channel, KeysAtCurrentTime[0], InValue);
}
else
{
const bool bHasAnyKeys = Channel->GetNumKeys() != 0;
if (bHasAnyKeys || bAutoSetTrackDefaults == false)
{
// When auto setting track defaults are disabled, add a key even when it's empty so that the changed
// value is saved and is propagated to the property.
AddKeyToChannel(Channel, CurrentTime, InValue, Interpolation);
}
if (bHasAnyKeys)
{
TRange<FFrameNumber> KeyRange = TRange<FFrameNumber>(CurrentTime);
TRange<FFrameNumber> SectionRange = OwningSection->GetRange();
if (!SectionRange.Contains(KeyRange))
{
OwningSection->SetRange(TRange<FFrameNumber>::Hull(KeyRange, SectionRange));
}
}
}
// Always update the default value when auto-set default values is enabled so that the last changes
// are always saved to the track.
if (bAutoSetTrackDefaults)
{
SetChannelDefault(Channel, InValue);
}
}
void OnChangeKey(int32 Selection, ESelectInfo::Type SelectionType)
{
FScopedTransaction Transaction(FText::FromString("Set FMOD Event Control Key Value"));
SetValue(Selection);
if (ISequencer *Sequencer = WeakSequencer.Pin().Get())
{
Sequencer->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::TrackValueChangedRefreshImmediately);
}
}
TMovieSceneChannelHandle<FFMODEventControlChannel> ChannelHandle;
TWeakObjectPtr<UMovieSceneSection> WeakSection;
TWeakPtr<ISequencer> WeakSequencer;
};
bool CanCreateKeyEditor(const FFMODEventControlChannel *Channel)
{
return true;
}
TSharedRef<SWidget> CreateKeyEditor(const TMovieSceneChannelHandle<FFMODEventControlChannel> &Channel, UMovieSceneSection *Section,
const FGuid &InObjectBindingID, TWeakPtr<FTrackInstancePropertyBindings> PropertyBindings, TWeakPtr<ISequencer> InSequencer)
{
const FFMODEventControlChannel *RawChannel = Channel.Get();
if (!RawChannel)
{
return SNullWidget::NullWidget;
}
UEnum *Enum = RawChannel->GetEnum();
return SNew(SFMODEventControlKeyEditor, Channel, Section, InSequencer, Enum);
}
void DrawKeys(FFMODEventControlChannel *Channel, TArrayView<const FKeyHandle> InKeyHandles, const UMovieSceneSection* InOwner, TArrayView<FKeyDrawParams> OutKeyDrawParams)
{
static const FName KeyLeftBrushName("Sequencer.KeyLeft");
static const FName KeyRightBrushName("Sequencer.KeyRight");
static const FName KeyDiamondBrushName("Sequencer.KeyDiamond");
const FSlateBrush *LeftKeyBrush = FAppStyle::GetBrush(KeyLeftBrushName);
const FSlateBrush *RightKeyBrush = FAppStyle::GetBrush(KeyRightBrushName);
const FSlateBrush *DiamondBrush = FAppStyle::GetBrush(KeyDiamondBrushName);
TMovieSceneChannelData<uint8> ChannelData = Channel->GetData();
for (int32 Index = 0; Index < InKeyHandles.Num(); ++Index)
{
FKeyHandle Handle = InKeyHandles[Index];
FKeyDrawParams Params;
Params.BorderBrush = Params.FillBrush = DiamondBrush;
const int32 KeyIndex = ChannelData.GetIndex(Handle);
if (KeyIndex != INDEX_NONE)
{
const EFMODEventControlKey Value = (EFMODEventControlKey)ChannelData.GetValues()[KeyIndex];
if (Value == EFMODEventControlKey::Play)
{
Params.BorderBrush = Params.FillBrush = LeftKeyBrush;
Params.FillOffset = FVector2D(-1.0f, 1.0f);
}
else if (Value == EFMODEventControlKey::Stop)
{
Params.BorderBrush = Params.FillBrush = RightKeyBrush;
Params.FillOffset = FVector2D(1.0f, 1.0f);
}
}
OutKeyDrawParams[Index] = Params;
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "MVVM/Views/KeyDrawParams.h"
#include "Channels/MovieSceneChannelHandle.h"
#include "Sequencer/FMODEventControlSection.h"
/** Key editor overrides */
bool CanCreateKeyEditor(const FFMODEventControlChannel* Channel);
TSharedRef<SWidget> CreateKeyEditor(const TMovieSceneChannelHandle<FFMODEventControlChannel>& Channel, UMovieSceneSection* Section,
const FGuid& InObjectBindingID, TWeakPtr<FTrackInstancePropertyBindings> PropertyBindings, TWeakPtr<ISequencer> InSequencer);
/** Key drawing overrides */
void DrawKeys(FFMODEventControlChannel *Channel, TArrayView<const FKeyHandle> InKeyHandles, const UMovieSceneSection* InOwner, TArrayView<FKeyDrawParams> OutKeyDrawParams);

View File

@ -0,0 +1,194 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#include "FMODEventControlTrackEditor.h"
#include "Rendering/DrawElements.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "Curves/IntegralCurve.h"
#include "SequencerSectionPainter.h"
#include "EditorStyleSet.h"
#include "Editor/UnrealEdEngine.h"
#include "Sequencer/FMODEventControlSection.h"
#include "Sequencer/FMODEventControlTrack.h"
#include "ISectionLayoutBuilder.h"
#include "FMODAmbientSound.h"
#include "CommonMovieSceneTools.h"
#include "Channels/MovieSceneChannelProxy.h"
#include "Channels/MovieSceneChannelEditorData.h"
#define LOCTEXT_NAMESPACE "FFMODEventControlTrackEditor"
FFMODEventControlSection::FFMODEventControlSection(UMovieSceneSection &InSection, TSharedRef<ISequencer> InOwningSequencer)
: Section(InSection)
, OwningSequencerPtr(InOwningSequencer)
{
}
UMovieSceneSection *FFMODEventControlSection::GetSectionObject()
{
return &Section;
}
float FFMODEventControlSection::GetSectionHeight() const
{
static const float SectionHeight = 20.f;
return SectionHeight;
}
int32 FFMODEventControlSection::OnPaintSection(FSequencerSectionPainter &InPainter) const
{
TSharedPtr<ISequencer> OwningSequencer = OwningSequencerPtr.Pin();
if (!OwningSequencer.IsValid())
{
return InPainter.LayerId + 1;
}
const ESlateDrawEffect DrawEffects = InPainter.bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;
const FTimeToPixel &TimeToPixelConverter = InPainter.GetTimeConverter();
FLinearColor TrackColor;
// TODO: Set / clip stop time based on event length
UFMODEventControlSection *ControlSection = Cast<UFMODEventControlSection>(&Section);
if (IsValid(ControlSection))
{
UFMODEventControlTrack *ParentTrack = Cast<UFMODEventControlTrack>(ControlSection->GetOuter());
if (IsValid(ParentTrack))
{
TrackColor = ParentTrack->GetColorTint();
}
}
// TODO: This should only draw the visible ranges.
TArray<TRange<float>> DrawRanges;
TOptional<float> CurrentRangeStart;
if (ControlSection != nullptr)
{
TMovieSceneChannelData<const uint8> ChannelData = ControlSection->ControlKeys.GetData();
TArrayView<const FFrameNumber> Times = ChannelData.GetTimes();
TArrayView<const uint8> Values = ChannelData.GetValues();
for (int32 Index = 0; Index < Times.Num(); ++Index)
{
const double Time = Times[Index] / TimeToPixelConverter.GetTickResolution();
const EFMODEventControlKey Value = (EFMODEventControlKey)Values[Index];
if (Value == EFMODEventControlKey::Play)
{
if (CurrentRangeStart.IsSet() == false)
{
CurrentRangeStart = Time;
}
}
if (Value == EFMODEventControlKey::Stop)
{
if (CurrentRangeStart.IsSet())
{
DrawRanges.Add(TRange<float>(CurrentRangeStart.GetValue(), Time));
CurrentRangeStart.Reset();
}
}
}
}
if (CurrentRangeStart.IsSet())
{
DrawRanges.Add(TRange<float>(CurrentRangeStart.GetValue(), OwningSequencer->GetViewRange().GetUpperBoundValue()));
}
for (const TRange<float> &DrawRange : DrawRanges)
{
float XOffset = TimeToPixelConverter.SecondsToPixel(DrawRange.GetLowerBoundValue());
float XSize = TimeToPixelConverter.SecondsToPixel(DrawRange.GetUpperBoundValue()) - XOffset;
FSlateDrawElement::MakeBox(InPainter.DrawElements, InPainter.LayerId,
InPainter.SectionGeometry.ToPaintGeometry(
FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2),
FVector2D(XSize, SequencerSectionConstants::KeySize.Y)),
FAppStyle::GetBrush("Sequencer.Section.Background"), DrawEffects);
FSlateDrawElement::MakeBox(InPainter.DrawElements, InPainter.LayerId,
InPainter.SectionGeometry.ToPaintGeometry(
FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2),
FVector2D(XSize, SequencerSectionConstants::KeySize.Y)),
FAppStyle::GetBrush("Sequencer.Section.BackgroundTint"), DrawEffects, TrackColor);
}
return InPainter.LayerId + 1;
}
FFMODEventControlTrackEditor::FFMODEventControlTrackEditor(TSharedRef<ISequencer> InSequencer)
: FMovieSceneTrackEditor(InSequencer)
{
}
TSharedRef<ISequencerTrackEditor> FFMODEventControlTrackEditor::CreateTrackEditor(TSharedRef<ISequencer> InSequencer)
{
return MakeShareable(new FFMODEventControlTrackEditor(InSequencer));
}
bool FFMODEventControlTrackEditor::SupportsType(TSubclassOf<UMovieSceneTrack> Type) const
{
return Type == UFMODEventControlTrack::StaticClass();
}
TSharedRef<ISequencerSection> FFMODEventControlTrackEditor::MakeSectionInterface(
UMovieSceneSection &SectionObject, UMovieSceneTrack &Track, FGuid ObjectBinding)
{
check(SupportsType(SectionObject.GetOuter()->GetClass()));
const TSharedPtr<ISequencer> OwningSequencer = GetSequencer();
return MakeShareable(new FFMODEventControlSection(SectionObject, OwningSequencer.ToSharedRef()));
}
void FFMODEventControlTrackEditor::BuildObjectBindingTrackMenu(FMenuBuilder &MenuBuilder, const TArray<FGuid> &ObjectBindings, const UClass *ObjectClass)
{
if (ObjectClass->IsChildOf(AFMODAmbientSound::StaticClass()) || ObjectClass->IsChildOf(UFMODAudioComponent::StaticClass()))
{
const TSharedPtr<ISequencer> ParentSequencer = GetSequencer();
MenuBuilder.AddMenuEntry(LOCTEXT("AddFMODEventControlTrack", "FMOD Event Control Track"),
LOCTEXT("FMODEventControlTooltip", "Adds a track for controlling FMOD event."), FSlateIcon(),
FUIAction(FExecuteAction::CreateSP(this, &FFMODEventControlTrackEditor::AddControlKey, ObjectBindings)));
}
}
void FFMODEventControlTrackEditor::AddControlKey(TArray<FGuid> ObjectGuids)
{
TSharedPtr<ISequencer> SequencerPtr = GetSequencer();
for (FGuid ObjectGuid : ObjectGuids)
{
UObject *Object = SequencerPtr.IsValid() ? SequencerPtr->FindSpawnedObjectOrTemplate(ObjectGuid) : nullptr;
if (Object)
{
AnimatablePropertyChanged(FOnKeyProperty::CreateRaw(this, &FFMODEventControlTrackEditor::AddKeyInternal, Object));
}
}
}
FKeyPropertyResult FFMODEventControlTrackEditor::AddKeyInternal(FFrameNumber KeyTime, UObject *Object)
{
FKeyPropertyResult KeyPropertyResult;
FFindOrCreateHandleResult HandleResult = FindOrCreateHandleToObject(Object);
FGuid ObjectHandle = HandleResult.Handle;
KeyPropertyResult.bHandleCreated |= HandleResult.bWasCreated;
if (ObjectHandle.IsValid())
{
FFindOrCreateTrackResult TrackResult = FindOrCreateTrackForObject(ObjectHandle, UFMODEventControlTrack::StaticClass());
UMovieSceneTrack *Track = TrackResult.Track;
KeyPropertyResult.bTrackCreated |= TrackResult.bWasCreated;
if (KeyPropertyResult.bTrackCreated && ensure(Track))
{
UFMODEventControlTrack *EventTrack = Cast<UFMODEventControlTrack>(Track);
EventTrack->AddNewSection(KeyTime);
EventTrack->SetDisplayName(LOCTEXT("TrackName", "FMOD Event"));
KeyPropertyResult.bTrackModified = true;
}
}
return KeyPropertyResult;
}
#undef LOCTEXT_NAMESPACE

View File

@ -0,0 +1,59 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#pragma once
#include "CoreMinimal.h"
#include "Misc/Guid.h"
#include "Templates/SubclassOf.h"
#include "Curves/KeyHandle.h"
#include "ISequencer.h"
#include "MovieSceneTrack.h"
#include "ISequencerSection.h"
#include "ISequencerTrackEditor.h"
#include "MovieSceneTrackEditor.h"
class FMenuBuilder;
class FSequencerSectionPainter;
/** FMOD Event control track */
class FFMODEventControlTrackEditor : public FMovieSceneTrackEditor
{
public:
FFMODEventControlTrackEditor(TSharedRef<ISequencer> InSequencer);
static TSharedRef<ISequencerTrackEditor> CreateTrackEditor(TSharedRef<ISequencer> OwningSequencer);
void AddControlKey(TArray<FGuid> ObjectGuids);
// Begin ISequencerTrackEditor interface
virtual void BuildObjectBindingTrackMenu(FMenuBuilder &MenuBuilder, const TArray<FGuid> &ObjectBindings, const UClass *ObjectClass) override;
virtual TSharedRef<ISequencerSection> MakeSectionInterface(
UMovieSceneSection &SectionObject, UMovieSceneTrack &Track, FGuid ObjectBinding) override;
virtual bool SupportsType(TSubclassOf<UMovieSceneTrack> Type) const override;
// End ISequencerTrackEditor interface
private:
/** Delegate for AnimatablePropertyChanged in AddKey. */
virtual FKeyPropertyResult AddKeyInternal(FFrameNumber KeyTime, UObject *Object);
};
/** Class for event control sections. */
class FFMODEventControlSection : public ISequencerSection, public TSharedFromThis<FFMODEventControlSection>
{
public:
FFMODEventControlSection(UMovieSceneSection &InSection, TSharedRef<ISequencer> InOwningSequencer);
// Begin ISequencerSection interface
virtual UMovieSceneSection *GetSectionObject() override;
virtual float GetSectionHeight() const override;
virtual int32 OnPaintSection(FSequencerSectionPainter &InPainter) const override;
virtual bool SectionIsResizable() const override { return false; }
// End ISequencerSection interface
private:
/** The section we are visualizing. */
UMovieSceneSection &Section;
/** The sequencer that owns this section */
TWeakPtr<ISequencer> OwningSequencerPtr;
};

View File

@ -0,0 +1,156 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#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<ISequencer> InSequencer)
: FMovieSceneTrackEditor(InSequencer)
{
}
TSharedRef<ISequencerTrackEditor> FFMODEventParameterTrackEditor::CreateTrackEditor(TSharedRef<ISequencer> OwningSequencer)
{
return MakeShareable(new FFMODEventParameterTrackEditor(OwningSequencer));
}
TSharedRef<ISequencerSection> FFMODEventParameterTrackEditor::MakeSectionInterface(
UMovieSceneSection &SectionObject, UMovieSceneTrack &Track, FGuid ObjectBinding)
{
UMovieSceneParameterSection *ParameterSection = Cast<UMovieSceneParameterSection>(&SectionObject);
checkf(ParameterSection != nullptr, TEXT("Unsupported section type."));
return MakeShareable(new FFMODParameterSection(*ParameterSection));
}
TSharedPtr<SWidget> FFMODEventParameterTrackEditor::BuildOutlinerEditWidget(
const FGuid &ObjectBinding, UMovieSceneTrack *Track, const FBuildEditWidgetParams &Params)
{
UFMODEventParameterTrack *EventParameterTrack = Cast<UFMODEventParameterTrack>(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<FGuid> &ObjectBindings, const UClass *ObjectClass)
{
if (ObjectClass->IsChildOf(AFMODAmbientSound::StaticClass()) || ObjectClass->IsChildOf(UFMODAudioComponent::StaticClass()))
{
const TSharedPtr<ISequencer> 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<UMovieSceneTrack> Type) const
{
return Type == UFMODEventParameterTrack::StaticClass();
}
TSharedRef<SWidget> FFMODEventParameterTrackEditor::OnGetAddParameterMenuContent(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack)
{
TSharedPtr<ISequencer> SequencerPtr = GetSequencer();
AFMODAmbientSound *Sound = SequencerPtr.IsValid() ? Cast<AFMODAmbientSound>(SequencerPtr->FindSpawnedObjectOrTemplate(ObjectBinding)) : nullptr;
UFMODAudioComponent *AudioComponent;
if (IsValid(Sound))
{
AudioComponent = Sound->AudioComponent;
}
else
{
AudioComponent = SequencerPtr.IsValid() ? Cast<UFMODAudioComponent>(SequencerPtr->FindSpawnedObjectOrTemplate(ObjectBinding)) : nullptr;
}
return BuildParameterMenu(ObjectBinding, EventParameterTrack, AudioComponent);
}
TSharedRef<SWidget> FFMODEventParameterTrackEditor::BuildParameterMenu(
FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack, UFMODAudioComponent *AudioComponent)
{
FMenuBuilder AddParameterMenuBuilder(true, nullptr);
if (IsValid(AudioComponent) && AudioComponent->Event)
{
TArray<FParameterNameAndAction> ParameterNamesAndActions;
TArray<FMOD_STUDIO_PARAMETER_DESCRIPTION> 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<AFMODAmbientSound>(Object.Get());
UFMODAudioComponent *AudioComponent = nullptr;
if (IsValid(Sound))
{
AudioComponent = Sound->AudioComponent;
}
else
{
AudioComponent = Cast<UFMODAudioComponent>(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

View File

@ -0,0 +1,77 @@
// Taken from ParticleParameterTrackEditor
#pragma once
#include "CoreMinimal.h"
#include "Misc/Guid.h"
#include "Templates/SubclassOf.h"
#include "Widgets/SWidget.h"
#include "ISequencer.h"
#include "MovieSceneTrack.h"
#include "ISequencerSection.h"
#include "Framework/Commands/UIAction.h"
#include "ISequencerTrackEditor.h"
#include "MovieSceneTrackEditor.h"
class FMenuBuilder;
class UFMODEventParameterTrack;
class UFMODAudioComponent;
struct FMOD_STUDIO_PARAMETER_DESCRIPTION;
/**
* Track editor for material parameters.
*/
class FFMODEventParameterTrackEditor : public FMovieSceneTrackEditor
{
public:
/** Constructor. */
FFMODEventParameterTrackEditor(TSharedRef<ISequencer> InSequencer);
/** Virtual destructor. */
virtual ~FFMODEventParameterTrackEditor() {}
/**
* Creates an instance of this class. Called by a sequencer.
*
* @param OwningSequencer The sequencer instance to be used by this tool.
* @return The new instance of this class.
*/
static TSharedRef<ISequencerTrackEditor> CreateTrackEditor(TSharedRef<ISequencer> OwningSequencer);
// ISequencerTrackEditor interface
virtual TSharedPtr<SWidget> BuildOutlinerEditWidget(
const FGuid &ObjectBinding, UMovieSceneTrack *Track, const FBuildEditWidgetParams &Params) override;
virtual TSharedRef<ISequencerSection> MakeSectionInterface(
UMovieSceneSection &SectionObject, UMovieSceneTrack &Track, FGuid ObjectBinding) override;
virtual bool SupportsType(TSubclassOf<UMovieSceneTrack> Type) const override;
private:
static FName TrackName;
// Struct used for building the parameter menu.
struct FParameterNameAndAction
{
FName ParameterName;
FUIAction Action;
FParameterNameAndAction(FName InParameterName, FUIAction InAction)
{
ParameterName = InParameterName;
Action = InAction;
}
bool operator<(FParameterNameAndAction const &Other) const { return ParameterName.FastLess(Other.ParameterName); }
};
void BuildObjectBindingTrackMenu(FMenuBuilder &MenuBuilder, const TArray<FGuid> &ObjectBindings, const UClass *ObjectClass);
/** Provides the contents of the add parameter menu. */
TSharedRef<SWidget> OnGetAddParameterMenuContent(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack);
TSharedRef<SWidget> BuildParameterMenu(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack, UFMODAudioComponent *AudioComponent);
bool CanAddEventParameterTrack(FGuid ObjectBinding);
void AddEventParameterTrack(FGuid ObjectBinding);
/** Adds an event parameter and initial key to a track. */
void AddParameter(FGuid ObjectBinding, UFMODEventParameterTrack *EventParameterTrack, FName ParameterName);
};

View File

@ -0,0 +1,25 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#include "FMODParameterSection.h"
#include "ISectionLayoutBuilder.h"
#include "ScopedTransaction.h"
#include "Sections/MovieSceneParameterSection.h"
#define LOCTEXT_NAMESPACE "FMODParameterSection"
bool FFMODParameterSection::RequestDeleteKeyArea(const TArray<FName> &KeyAreaNamePath)
{
if (KeyAreaNamePath.Num() == 1)
{
const FScopedTransaction Transaction(LOCTEXT("DeleteEventParameter", "Delete event parameter"));
UMovieSceneParameterSection *ParameterSection = Cast<UMovieSceneParameterSection>(WeakSection.Get());
if (ParameterSection->TryModify())
{
return ParameterSection->RemoveScalarParameter(KeyAreaNamePath[0]);
}
}
return true;
}
#undef LOCTEXT_NAMESPACE

View File

@ -0,0 +1,21 @@
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
#pragma once
#include "ISequencerSection.h"
class UMovieSceneSection;
/** A movie scene section for Event parameters. */
class FFMODParameterSection : public FSequencerSection
{
public:
FFMODParameterSection(UMovieSceneSection &InSectionObject)
: FSequencerSection(InSectionObject)
{
}
// Begin ISequencerSection interface
virtual bool RequestDeleteKeyArea(const TArray<FName> &KeyAreaNamePath) override;
// End ISequencerSection interface
};