UnrealEngine4로 자신의 게임 전용 ProjectSettings 추가

전제


  • UnrealEngine 4.24.1 (Launcher engine)
  • VisualStudio 2019
  • C++ 프로젝트를 빌드 할 수있는 환경이라면 무엇이든 좋다

  • 어느 정도의 UnrealC++에 대한 지식
  • UPROPERTY란 무엇입니까? 레벨에 대한 설명은 없습니다


  • 이전 프리



    AnswerHub에서 화제가 나왔기 때문에 샘플을 만들었습니다.
    최소한 움직이는 것을 목표로 했으므로, 구체적인 부분은 각자로 읽어주고 싶다

    UE4.24.1에서 검증하고 있지만 이 내용 자체는 이전 버전에도 적용 가능

    만드는 방법



    먼저 C++ 프로젝트를 만들어 봅시다.
    템플릿은 무엇이든 좋은
    예제에서는 ThirdPersonTemplate(StarterContents 포함)을 사용합니다.

    설정용 Class 만들기



    새로운 C++ 클래스에서 UObject 상속 클래스를 하나 만들자.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 클래스가 없기 때문에 여기를 필기로 만듭니다.
    (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에 항목이 추가되었음을 알 수 있습니다.




    모처럼이므로 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 내에서 사용할 수 있습니다.


    주의점



    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++에 익숙한 사람은 이것으로 대체로 알아볼 수 있습니다만, 익숙하지 않은 사람은 "왜? 디버그에서는 움직이고 있었잖아"라고 외치게 될 것입니다

    참고 자료

    좋은 웹페이지 즐겨찾기