くーこのプログラマメモ

UE4などゲーム開発に関するメモ

プロパティ(構造体)やクラスのレイアウトカスタマイズの登録/解除

使用バージョン:UE4.24.3

目的

エディタ上でのプロパティ(構造体)やクラスのレイアウトカスタマイズを使用する際の登録/解除の処理をFDetailCustomizationsModuleより抜粋したメモです。

準備

以下のモジュールを依存関係として追加する必要があります。

  • PropertyEditor

コード

モジュールh

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "PropertyEditorDelegates.h"


class FExampleModule : public IModuleInterface
{
private:
    /** 登録クラスリスト */
    TSet<FName>                               RegisteredClassNames;
    /** 登録プロパティリスト */
    TSet<FName>                               RegisteredPropertyTypes;
public:

    /** IModuleInterface implementation */
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;

private:
    /** クラスレイアウトカスタマイズ登録をまとめた関数 */
    void   RegisterCustomClassLayouts();
    /** プロパティレイアウトカスタマイズ登録をまとめた関数 */
    void   RegisterCustomProperties();

    /** クラスレイアウトカスタマイズ登録 */
    void   RegisterCustomClassLayout(FName ClassName, FOnGetDetailCustomizationInstance DetailLayoutDelegate);
    /** プロパティレイアウトカスタマイズ登録 */
    void   RegisterCustomPropertyTypeLayout(FName PropertyTypeName, FOnGetPropertyTypeCustomizationInstance PropertyTypeLayoutDelegate);
    /** 全てのレイアウトカスタマイズ登録解除 */
    void   UnregisterAllCustomLayouts();
};

モジュールcpp

#include "ExampleModule.h"
#include "PropertyEditorModule.h"

#define LOCTEXT_NAMESPACE "FExampleModule"



void FExampleModule::StartupModule()
{
    if (!IsRunningGame() && !IsRunningDedicatedServer())
    {
        this->RegisterCustomClassLayouts();
        this->RegisterCustomProperties();

        // カスタマイズモジュールへ変更を通知.
        FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
        PropertyModule.NotifyCustomizationModuleChanged();
    }
}
//---

void FExampleModule::ShutdownModule()
{
    this->UnregisterAllCustomLayouts();
}
//---



void
FExampleModule::RegisterCustomClassLayouts()
{
    // クラスレイアウトカスタマイズ登録.
}
//---

void
FExampleModule::RegisterCustomProperties()
{
    // プロパティレイアウトカスタマイズ登録.
}
//---


void
FExampleModule::RegisterCustomClassLayout(FName ClassName, FOnGetDetailCustomizationInstance DetailLayoutDelegate)
{
    check(ClassName != NAME_None);

    this->RegisteredClassNames.Add(ClassName);

    static FName PropertyEditor("PropertyEditor");
    FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>(PropertyEditor);
    PropertyModule.RegisterCustomClassLayout(ClassName, DetailLayoutDelegate);
}
//---

void
FExampleModule::RegisterCustomPropertyTypeLayout(FName PropertyTypeName, FOnGetPropertyTypeCustomizationInstance PropertyTypeLayoutDelegate)
{
    check(PropertyTypeName != NAME_None);

    this->RegisteredPropertyTypes.Add(PropertyTypeName);

    static FName PropertyEditor("PropertyEditor");
    FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>(PropertyEditor);
    PropertyModule.RegisterCustomPropertyTypeLayout(PropertyTypeName, PropertyTypeLayoutDelegate);
}
//---

void
FExampleModule::UnregisterAllCustomLayouts()
{
    if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
    {
        FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");

        // Unregister all classes customized by name
        for (auto It = this->RegisteredClassNames.CreateConstIterator(); It; ++It)
        {
            if (It->IsValid())
            {
                PropertyModule.UnregisterCustomClassLayout(*It);
            }
        }

        // Unregister all structures
        for (auto It = this->RegisteredPropertyTypes.CreateConstIterator(); It; ++It)
        {
            if (It->IsValid())
            {
                PropertyModule.UnregisterCustomPropertyTypeLayout(*It);
            }
        }

        PropertyModule.NotifyCustomizationModuleChanged();
    }
}
//---


#undef LOCTEXT_NAMESPACE
    
IMPLEMENT_MODULE(FExampleModule, Example)