LoginSignup
13
5

More than 3 years have passed since last update.

UnrealEngine4で自分のゲーム専用のProjectSettingsを追加する

Posted at

前提

  • UnrealEngine 4.24.1 (Launcher engine)
  • VisualStudio 2019
    • C++プロジェクトのビルドができる環境なら何でも良い
  • ある程度のUnrealC++についての知識
    • UPROPERTYとはなんぞや?レベルの解説はしません

前フリ

AnswerHubで話題が出たのでサンプルを作りました
最低限動くものを目指したので、具体的な部分は各自で読み替えていただきたく

UE4.24.1で検証していますが、この内容自体はもっと前のバージョンでも適用可能です

作り方

まずC++プロジェクトを作成しておきましょう
テンプレートは何でも良いです
例では、ThirdPersonTemplate(StarterContentsあり)を使用します

設定用のClassを作る

新規C++クラスから、UObject継承クラスを1つ作成しましょう
MyGameSettingsとでもしておきます

VisualStudioに移ったら、以下のように書いておきましょう
Propertyに関しては、お好きなものをチョイスしてください
今回はActorのClassReferenceを使います

また、それぞれのUPROPERTYにconfigと書き加えておきましょう

MyGameSettings.h

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "MyGameSettings.generated.h"

UCLASS(config=Game, defaultconfig)
class CPP424_API UMyGameSettings : public UObject
{
    GENERATED_BODY()

public:

    UMyGameSettings(const FObjectInitializer& ObjectInitializer);

    UPROPERTY(EditAnywhere, config, Category="MyGameSettings", meta = (AllowedClasses = "Actor"))
    TSubclassOf< class AActor > DefaultSpawnActor;

};

設定をProjectSettingsで編集できるようにする

ProjectSettingsに項目を追加します
Moduleロード時に登録するようにします

テンプレートからではこのModuleのクラスがないため、ここは手書きで作ることになります
(Plugin開発ではModuleが独立しているのでModuleクラスがあります)

C++のソース内に[ProjectName].hがあります(自分のProject名で置き換えてね)
これがModuleにあたります
せっかくなのでこれを使いましょう

[ProjectName].h
#pragma once

#include "CoreMinimal.h"
#include "MyGameSettings.h"

#if WITH_EDITOR
// SettingsモジュールはEditor用のため、Packaging時には参照しないようにしておく
#include "ISettingsModule.h"
#include "ISettingsSection.h"
#include "ISettingsContainer.h"
#endif

#define LOCTEXT_NAMESPACE "FCustomSettingsModule"

class FCustomSettingsModule : public FDefaultGameModuleImpl
{
    // モジュールロード時
    virtual void StartupModule() override
    {
        // 設定を登録する
        RegisterSettings();
    }

    // モジュールアンロード時
    virtual void ShutdownModule() override
    {
        if (UObjectInitialized()) {
            // 設定を登録解除する
            UnregisterSettings();
        }
    }

    virtual bool SupportsDynamicReloading() override
    {
        // DynamicReloadingはON
        return true;
    }

private:
    // 設定を保存する
    bool HandleSettingsSaved()
    {
        UMyGameSettings* Settings = GetMutableDefault<UMyGameSettings>();
        bool ResaveSettings = false;

        if (ResaveSettings)
        {
            Settings->SaveConfig();
        }

        return true;
    }

    // 設定を登録する
    void RegisterSettings()
    {

#if WITH_EDITOR
        // Settingsモジュールを取得
        if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
        {
            // 設定用のカテゴリーを追加する
            ISettingsSectionPtr SettingsSection = SettingsModule->RegisterSettings("Project", "CustomSettings", "General",
                LOCTEXT("RuntimeGeneralSettingsName", "General"),
                LOCTEXT("RuntimeGeneralSettingsDescription", "MyConfiguration"),
                GetMutableDefault<UMyGameSettings>());

            if (SettingsSection.IsValid())
            {
                // 更新時の自動保存処理を登録
                SettingsSection->OnModified().BindRaw(this, &FCustomSettingsModule::HandleSettingsSaved);
            }
        }
#endif
    }

    // 設定を登録解除する
    void UnregisterSettings()
    {
#if WITH_EDITOR
        // Settingsモジュールを取得
        if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
        {
            // カテゴリーごと削除する
            SettingsModule->UnregisterSettings("Project", "CustomSettings", "General");
        }
#endif
    }
};

#undef LOCTEXT_NAMESPACE

[ProjectName].cppの方も書き換えます(自分のProject名で置き換えてね)
FDefaultGameModuleImplの部分が、先程書いたクラス名になっていればOKです

#include "[ProjectName].h"
#include "Modules/ModuleManager.h"

//IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, [ProjectName], "[ProjectName]");
IMPLEMENT_PRIMARY_GAME_MODULE(FCustomSettingsModule, [ProjectName], "[ProjectName]");

ここまで出来たらコンパイルしましょう
コンパイルが完了したら、ProjectSettingsをチェックしてみてください
ProjectSettingsに項目が追加されているのがわかります
image.png

おまけ

せっかくなのでBlueprintで使えるようにしてみましょう
BlueprintFunctionLibraryを追加します

MySettingsFunctionLibrary.h
#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyGameSettings.h"
#include "MySettingsFunctionLibrary.generated.h"

/**
 *
 */
UCLASS()
class CPP424_API UMySettingsFunctionLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()


public:
    // デフォルトActorのクラス名を取得する
    UFUNCTION(BlueprintPure, Category = "MyGameSettings")
        static TSubclassOf<class AActor> GetDefaultSpawnActorClass()
    {
        // 設定をロードする
        UMyGameSettings* Settings = GetMutableDefault<UMyGameSettings>();

        return Settings->DefaultSpawnActor;

    }

};

こうしておけばProjectSettingsで設定した値が、Blueprint内で使えますね
image.png

注意点

SettingsモジュールはEditor用のモジュールであり、Package時には参照できません
なのでSettingsモジュールを使っている部分は必ず#if WITH_EDITOR ~ #endifで囲んでおき、Packaging時に参照されないようにしておきましょう
この点を知らないと、下記のようなエラーが出てくるため、大変混乱することになります

fatal error C1083: Cannot open include file: 'ISettingsModule.h': No such file or directory

UnrealEngineのC++に慣れてる人はこれでだいたい察せますが、慣れてない人は「なんで?デバッグでは動いてたじゃん」と叫ぶことになるでしょう

参考資料

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5