目標
UE4のシーケンサーのエディター拡張を行い、メニューの項目を追加してシーケンサーに対して独自の処理を行うための入り口を作りたい。
※エンジン改造はしません。
今回はシーケンサーのトラックメニューに追加する方法になります。
具体的には以下の画像の箇所
前回の続きで対応するため、以下もご一読ください。
naoxgames.hatenablog.jp
環境
・UE 4.26.1 (エンジンビルドはしていません)
・VisualStudio 2019 16.7.2
やってみる
作戦としては前回同様UI拡張点からコードを検索して、似た処理を真似てみます。
前回のプラグインに処理を追加して対応します。
UIの拡張点の表示
前回同様UIの拡張点の表示を行いましょう。
※UE4エディターの[編集]→[エディタの環境設定]→[UIの拡張点の表示]にチェックを入れます。
該当箇所を確認すると
「ObjectBindings」ということがわかりました。
エンジンから類似処理を探す
「ObjectBindings」でエンジンのコードを検索すると、SSequencer.cpp
のSSequencer::GetContextMenuContent
で使われていることがわかります。
FSequencer::BuildAddObjectBindingsMenu
を見ると、ObjectBindings[i]->BuildSequencerAddMenu
でメニューの登録がされています。
トラックメニューに表示されるにはこのObjectBindings
に登録されている必要があるようです。
ObjectBindings
に登録する処理を探すとFSequencer::InitSequencer
でObjectBindings.Add
されているのが確認できます。
EditorObjectBindingDelegates
の要素数分登録されているので、FSequencer::InitSequencer
の引数のEditorObjectBindingDelegates
がどこでどう設定されているか確認します。
FSequencer::InitSequencer
を検索するとFSequencerModuleのCreateSequencer
で呼び出しています。
EditorObjectBindingDelegates
に登録する処理はFSequencerModuleのRegisterEditorObjectBinding
で行っています。
っということで、必要な情報は揃いました。
モジュール設定
SequenceExtensionEd.Build.csに以下を追加します。
~ PublicDependencyModuleNames.AddRange( new string[] { ~ "Sequencer", ~ } ); ~
シーケンサーモジュールに拡張メニュー追加
トラックメニューに追加する処理を作成します。
ObjectBindingExtension.h
#include "CoreMinimal.h" #include "ISequencerEditorObjectBinding.h" /** * */ class ISequencer; class AActor; class FObjectBindingExtension : public ISequencerEditorObjectBinding { public: FObjectBindingExtension(TSharedRef<ISequencer> InSequencer); static TSharedRef<ISequencerEditorObjectBinding> OnCreateActorBinding(TSharedRef<ISequencer> inSequencer); // ISequencerEditorObjectBinding interface virtual void BuildSequencerAddMenu(FMenuBuilder& MenuBuilder) override; virtual bool SupportsSequence(UMovieSceneSequence* InSequence) const override; private: void AddObjectBindingMenuExtension(); private: TWeakPtr<ISequencer> Sequencer; };
ObjectBindingExtension.cpp
#include "ObjectBindingExtension.h" #include "Misc/Guid.h" #include "EditorStyleSet.h" #include "LevelSequence.h" #define LOCTEXT_NAMESPACE "FObjectBindingExtension" FObjectBindingExtension::FObjectBindingExtension(TSharedRef<ISequencer> InSequencer) : Sequencer(InSequencer) { } TSharedRef<ISequencerEditorObjectBinding> FObjectBindingExtension::OnCreateActorBinding(TSharedRef<ISequencer> inSequencer) { return MakeShareable(new FObjectBindingExtension(inSequencer)); } void FObjectBindingExtension::BuildSequencerAddMenu(FMenuBuilder& MenuBuilder) { MenuBuilder.AddMenuEntry( LOCTEXT("ObjectBindingEx", "ObjectBindingEx"), LOCTEXT("ObjectBindingToolTip", "ObjectBindingToolTip"), FSlateIcon(FEditorStyle::GetStyleSetName(), "ContentBrowser.ColumnViewAssetIcon"), FUIAction(FExecuteAction::CreateRaw(this, &FObjectBindingExtension::AddObjectBindingMenuExtension))); } bool FObjectBindingExtension::SupportsSequence(UMovieSceneSequence* InSequence) const { return InSequence->GetClass() == ULevelSequence::StaticClass(); } void FObjectBindingExtension::AddObjectBindingMenuExtension() { FText DialogText = FText::FromString("ObjectBindingMenuExtension"); FMessageDialog::Open(EAppMsgType::Ok, DialogText); } #undef LOCTEXT_NAMESPACE
SequencerExtensionEd.h
~ private: ~ FDelegateHandle ObjectBindingDelegateHandle; ~
SequencerExtensionEd.cpp
~ #include "ObjectBindingExtension.h" ~ void FSequencerExtensionEdModule::StartupModule() { ~ ObjectBindingDelegateHandle = SequencerModule.RegisterEditorObjectBinding(FOnCreateEditorObjectBinding::CreateStatic(&FObjectBindingExtension::OnCreateActorBinding)); ~ } ~ void FSequencerExtensionEdModule::ShutdownModule() { ~ SequencerModule.UnRegisterEditorObjectBinding(ObjectBindingDelegateHandle); ~ }
実行!!!!
シーケンサーのトラックメニューに項目が指定した名前で追加され、ダイアログが表示されました。
思ったこと
前回とは違った追加の仕方で、メニューごとに違うとやりにくいですね。
以前に書いた記事で、ISequencerを取得する対応を紹介しています。
naoxgames.hatenablog.jp
これと組み合わせることでメニューからできることの幅が広がると思います。
ここまでの内容は以下のリポジトリに上げてあります。
github.com
この記事の続き
naoxgames.hatenablog.jp
正しい対応方法やより良い方法があればご指摘お願いいたします!!!