Help us understand the problem. What is going on with this article?

[UE4]利便性を上げるちょっとしたエンジン改造

  • 本記事に関して
    • 確認バージョン: UE4.23.1
    • エンジン改造のみ

ちょっとだけ何か弄りたくなった所を纏めました。

ツールバーを整理する

image.png

コンテンツブラウザ、マーケットボタンを消す

image.png
コンテンツブラウザはメニューバーから出せます。
マーケットプレイスはそうエディターから頻繁に行かない……
image.png

After
image.png
使用頻度の低いアイコンを消しました。

  • LevelEditorToolBar.cpp 1255行辺り : FLevelEditorToolBar::MakeLevelEditorToolBar内
    • ツールバーに追加している箇所をビルドから除外します。

サンプルコード
LevelEditorToolBar.cpp
    ToolbarBuilder.BeginSection("Content");
#if 0 // [com04] 消す
    {
        ToolbarBuilder.AddToolBarButton( FLevelEditorCommands::Get().OpenContentBrowser, NAME_None, LOCTEXT( "ContentBrowser_Override", "Content" ), TAttribute<FText>(), TAttribute<FSlateIcon>(), "LevelToolbarContent" );
        if (FLauncherPlatformModule::Get()->CanOpenLauncher(true)) 
        {
            ToolbarBuilder.AddToolBarButton(FLevelEditorCommands::Get().OpenMarketplace, NAME_None, LOCTEXT("Marketplace_Override", "Marketplace"), TAttribute<FText>(), TAttribute<FSlateIcon>(), "LevelToolbarMarketplace");
        }
    }
#endif // [com04]
    ToolbarBuilder.EndSection();

ビルド、コンパイルボタンを1クリックで動作させなくする

image.png
「プレイ」ボタン押そうとして誤クリックでライティングビルドが始まったり、C++コンパイルが走ったりした人も多いはず……!
とはいえ使うボタンですので今回は消すのではなく、1クリックでは動作しないようにして誤クリックを防止します。

After


1クリックでビルド/コンパイルが動作しないようになりました。
ビルド/コンパイルはサブメニューに移動しました
image.png
image.png

ビルドボタン

  • LevelEditorToolBar.cpp 1440行辺り : FLevelEditorToolBar::MakeLevelEditorToolBar内
    • まずは「ビルド」ボタンを削除。右横の「▼」をボタン付きメニューとして扱います

コード
LevelEditorToolBar.cpp
    ToolbarBuilder.BeginSection("Compile");
    {
#if 1 // [com04]
        // Build menu drop down
        ToolbarBuilder.AddComboButton(
            FUIAction(),
            FOnGetContent::CreateStatic(&FLevelEditorToolBar::GenerateBuildMenuContent, InCommandList),
            LOCTEXT("BuildAll", "Build"),
            LOCTEXT("BuildAll", "Build"),
            FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Build"),
            false);
#else
        // Build            
        ToolbarBuilder.AddToolBarButton( FLevelEditorCommands::Get().Build, NAME_None, LOCTEXT("BuildAll", "Build") );

        // Build menu drop down
        ToolbarBuilder.AddComboButton(
            FUIAction(),
            FOnGetContent::CreateStatic( &FLevelEditorToolBar::GenerateBuildMenuContent, InCommandList ),
            LOCTEXT( "BuildCombo_Label", "Build Options" ),
            LOCTEXT( "BuildComboToolTip", "Build options menu" ),
            FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Build"),
            true);
#endif // [com04]

  • LevelEditorToolBar.cpp 1730行辺り FLevelEditorToolBar::GenerateBuildMenuContent内
    • このままだとビルドボタンが消えたままなので、クリック後に出てくるメニューに追加します

コード
LevelEditorToolBar.cpp
    // [com04] ----
    MenuBuilder.AddMenuEntry(FLevelEditorCommands::Get().Build, NAME_None, LOCTEXT("BuildAll", "Build"));
    // ---- [com04]

    MenuBuilder.BeginSection("LevelEditorLighting", LOCTEXT( "LightingHeading", "Lighting" ) );
    {

コンパイルボタン

  • LevelEditorToolBar.cpp 1454行辺り : FLevelEditorToolBar::MakeLevelEditorToolBar内
    • 「コンパイル」ボタンを削除。右側のオプション「▼」をボタン付きメニューとして表示します

サンプルコード
LevelEditorToolBar.cpp
        if ( FSourceCodeNavigation::IsCompilerAvailable() )
        {
#if 1 // [com04]
            ToolbarBuilder.AddComboButton(
                FUIAction(
                    FExecuteAction(),
                    FCanExecuteAction(),
                    FIsActionChecked(),
                    FIsActionButtonVisible::CreateStatic(FLevelEditorActionCallbacks::CanShowSourceCodeActions)),
                FOnGetContent::CreateStatic(&FLevelEditorToolBar::GenerateCompileMenuContent, InCommandList),
                LOCTEXT( "CompileMenuButton", "Compile" ),
                LOCTEXT( "CompileMenuButton", "Compile" ),
                FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Recompile"),
                false
            );
#else
            // Since we can always add new code to the project, only hide these buttons if we haven't done so yet
            ToolbarBuilder.AddToolBarButton(
                FUIAction(
                    FExecuteAction::CreateStatic(&FLevelEditorActionCallbacks::RecompileGameCode_Clicked),
                    FCanExecuteAction::CreateStatic(&FLevelEditorActionCallbacks::Recompile_CanExecute),
                    FIsActionChecked(),
                    FIsActionButtonVisible::CreateStatic(FLevelEditorActionCallbacks::CanShowSourceCodeActions)),
                NAME_None,
                LOCTEXT( "CompileMenuButton", "Compile" ),
                FLevelEditorCommands::Get().RecompileGameCode->GetDescription(),
                FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Recompile")
            );

#if WITH_LIVE_CODING
            ToolbarBuilder.AddComboButton(
                FUIAction(
                    FExecuteAction(),
                    FCanExecuteAction(),
                    FIsActionChecked(),
                    FIsActionButtonVisible::CreateStatic(FLevelEditorActionCallbacks::CanShowSourceCodeActions)), 
                FOnGetContent::CreateStatic( &FLevelEditorToolBar::GenerateCompileMenuContent, InCommandList ),
                LOCTEXT( "CompileCombo_Label", "Compile Options" ),
                LOCTEXT( "CompileComboToolTip", "Compile options menu" ),
                FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Recompile"),
                true
                );
#endif
#endif // [com04]

  • LevelEditorToolBar.cpp 1900行辺り : FLevelEditorToolBar::GenerateCompileMenuContent辺り
    • 消えた「コンパイル」ボタンをメニュー内に追加します

サンプルコード
LevelEditorToolBar.cpp
// #if WITH_LIVE_CODING // [com04] コメント化
TSharedRef< SWidget > FLevelEditorToolBar::GenerateCompileMenuContent( TSharedRef<FUICommandList> InCommandList )
{
#define LOCTEXT_NAMESPACE "LevelToolBarCompileMenu"

    const bool bShouldCloseWindowAfterMenuSelection = true;
    FMenuBuilder MenuBuilder( bShouldCloseWindowAfterMenuSelection, InCommandList );

    MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().RecompileGameCode );  // [com04] コンパイルボタン追加

#if WITH_LIVE_CODING // [com04]
    MenuBuilder.BeginSection("LiveCodingMode", LOCTEXT( "LiveCodingMode", "General" ) );
    {
        MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().LiveCoding_Enable );
    }
    MenuBuilder.EndSection();

    MenuBuilder.BeginSection("LiveCodingActions", LOCTEXT( "LiveCodingActions", "Actions" ) );
    {
        MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().LiveCoding_StartSession );
        MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().LiveCoding_ShowConsole );
        MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().LiveCoding_Settings );
    }
    MenuBuilder.EndSection();
#endif // [com04]

    return MenuBuilder.MakeWidget();

#undef LOCTEXT_NAMESPACE
}
// #endif // [com04] コメント化

  • LevelEditorToolBar.h 36行辺り : FLevelEditorToolBar GenerateCompileMenuContent辺り
    • ヘッダのコメントアウトも解除しておきます

サンプルコード
LevelEditorToolBar.h
// #if WITH_LIVE_CODING // [com04]
    /**
     * Generates menu content for the compile combo button drop down menu
     *
     * @return  Menu content widget
     */
    static TSharedRef< SWidget > GenerateCompileMenuContent( TSharedRef<FUICommandList> InCommandList );
// #endif // [com04]

Viewportのツールバーに機能を追加する

image.png
エディター上のViewport、割と使いやすいです。
この左上の「▼」にプロジェクト固有の処理を追加します。内部的には普通にslateを追加する感じです。

  • SLevelViewportToolBar.h 194行辺り : SLevelViewportToolBar OnScreenPercentageValueChanged辺り
    • 登録するウィジェット(今回はSSpinBox)生成関数と、そのウィジェットのイベント周りの関数を宣言します

サンプルコード
LevelEditorToolBar.h
    void OnScreenPercentageValueChanged(int32 NewValue);

// [com04] ----
    /* 追加するウィジェット作る */
    TSharedRef<SWidget> GenerateProjectParamMenu() const;
    /* パラメーター数値 */
    int32 OnGetProjectParamValue() const;
    /* パラメーターの数値が変わったイベント */
    void OnProjectParamValueChanged(int32 NewValue);
    int32 TestValue = 0;
// ---- [com04]

  • SLevelViewportToolBar.cpp 1140行辺り : SLevelViewportToolBar::OnScreenPercentageValueChanged辺り
    • 宣言した関数を実装します。SSpinBox生成とそのイベントハンドリングです。

サンプルコード
LevelEditorToolBar.cpp
// [com04] ----
/* 追加するウィジェット作る */
TSharedRef<SWidget> SLevelViewportToolBar::GenerateProjectParamMenu() const
{
    return
        SNew(SBox)
        .HAlign(HAlign_Right)
        [
            SNew(SBox)
            .Padding(FMargin(4.0f, 0.0f, 0.0f, 0.0f))
        .WidthOverride(100.0f)
        [
            SNew(SSpinBox<int32>)
            .Font(FEditorStyle::GetFontStyle(TEXT("MenuItem.Font")))
        .MinValue(0)
        .MaxValue(100)
        .Value(this, &SLevelViewportToolBar::OnGetProjectParamValue)
        .OnValueChanged(const_cast<SLevelViewportToolBar*>(this), &SLevelViewportToolBar::OnProjectParamValueChanged)
        ]
        ];
}
/* パラメーター数値 */
int32 SLevelViewportToolBar::OnGetProjectParamValue() const
{
    // 今の値を返す
    return TestValue;
}
/* パラメーターの数値が変わったイベント */
void SLevelViewportToolBar::OnProjectParamValueChanged(int32 NewValue)
{
    // プロジェクトの何かする
    TestValue = NewValue;
}
// ---- [com04]

TSharedRef<SWidget> SLevelViewportToolBar::GenerateFarViewPlaneMenu() const

  • SLevelViewportToolBar.cpp 555行辺り : SLevelViewportToolBar::GenerateOptionsMenu辺り
    • メニューを構築している所に差し込みます

サンプルコード
LevelEditorToolBar.cpp
            OptionsMenuBuilder.AddWidget(GenerateScreenPercentageMenu(), LOCTEXT("ScreenPercentage", "Screen Percentage"));
// [com04] ----
            OptionsMenuBuilder.AddWidget(GenerateProjectParamMenu(), LOCTEXT("ProjectParam", "project param ya"));
// ---- [com04]
        }
        OptionsMenuBuilder.EndSection();

マテリアルエディターのStat欄に使用しているMaterial Parameter Collectionを出力する

マテリアルではMaterial Parameter Collectionを最大2つまで使用できます
3つ以上になるとエラーが出ます
image.png

しかし、今現在、何個使っているのか、何のMaterial Parameter Collectionを使っているのかが分かりません。

という事で出力してみました
image.png

エラー時もどれ使ってるのか分かるように
image.png

  • MaterialEditor.cpp 2144行辺り : FMaterialEditor::UpdateMaterialinfoList_Old内
    • Statの結果を出している所に差し込みます

サンプルコード
MaterialEditor.cpp
            }

            // [com04] ----
            if (MaterialForStats)
            {
                FString CollectionString;

                /* マテリアルに入っているMPCのリスト */
                for (const auto& CollectionInfo : MaterialForStats->MaterialParameterCollectionInfos)
                {
                    if (CompileErrors.Num())
                    {
                        /* エラー出てる時は全部出力する */
                    }
                    else
                    {
                        bool Used = false;
                        /* コンパイル時に使用されているMPCのリスト */
                        FMaterialRenderProxy* RenderProxy = MaterialForStats->GetRenderProxy();
                        if (RenderProxy)
                        {
                            for (const auto& Collection : RenderProxy->UniformExpressionCache[GMaxRHIFeatureLevel].ParameterCollections)
                            {
                                if (Collection == CollectionInfo.StateId)
                                {
                                    Used = true;
                                    break;
                                }
                            }
                        }
                        /* このMPC使ってない */
                        if (Used == false)
                        {
                            continue;
                        }
                    }
                    const UMaterialParameterCollection* Collection = CollectionInfo.ParameterCollection;
                    if (Collection)
                    {
                        if (CollectionString.IsEmpty())
                        {
                            CollectionString = Collection->GetName();
                        }
                        else
                        {
                            CollectionString += FString::Printf(TEXT(", %s"), *Collection->GetName());
                        }
                    }
                }
                if (!CollectionString.IsEmpty())
                {
                    FString CollectionMessage(FString::Printf(TEXT("Collectins: %s"), *CollectionString));
                    TempMaterialInfoList.Add(MakeShareable(new FMaterialInfo(CollectionMessage, FLinearColor::Yellow)));
                    TSharedRef<FTokenizedMessage> Line = FTokenizedMessage::Create(EMessageSeverity::Info);
                    Line->AddToken(FTextToken::Create(FText::FromString(CollectionMessage)));
                    Messages.Add(Line);
                }
            }
            // ---- [com04]


            FString FeatureLevelName;
            GetFeatureLevelName(FeatureLevel,FeatureLevelName);
            for(int32 ErrorIndex = 0; ErrorIndex < CompileErrors.Num(); ErrorIndex++)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした