...

суббота, 16 января 2016 г.

Система плагинов и модулей в Unreal Engine 4


Здравствуйте меня зовут Дмитрий. Я занимаюсь созданием компьютерных игр на Unreal Engine в качестве хобби. Сегодня я расскажу как создать свой модуль, а потом как создать плагин в Unreal Engine 4.

Создание модуля

Итак начнем с модулей. Когда вы создаете проект, в файле проекта автоматически создается один модуль.

{
        "FileVersion": 3,
        "EngineAssociation": "4.10",
        "Category": "",
        "Description": "",
        "Modules": [
                {
                        "Name": "UICustom",
                        "Type": "Runtime",
                        "LoadingPhase": "Default"
                        
                }
        ]
}


В принципе для простого проекта это достаточно. Но если вы читали мою предыдущую статью (а если не читали то советую сделать это прямо сейчас) можно увидеть что определенный код, который необходим для регистрации ассета, добавлении кнопок на панель свойств этого ассета, для игры нам не нужен, а нужен только для редактора. Поэтому было-бы хорошо сделать так чтобы, при сборке игры этот код в игру не включался, именно для этого и предназначена система модулей.

Итак начнем. Сначала добавим ещё один модуль:

{
        "FileVersion": 3,
        "EngineAssociation": "4.10",
        "Category": "",
        "Description": "",
        "Modules": [
                {
                        "Name": "UICustom",
                        "Type": "Runtime",
                        "LoadingPhase": "Default"
                        
                },
                {
                        "Name": "UICustomEditor",
                        "Type": "Editor",
                        "LoadingPhase": "Default"
                        
                }
        ]
}

Параметры модуля
У модуля имеются параметр тип, который определяет куда следует включать модуль, а куда нет. Тип может принимать следующие значения:
namespace EHostType
{
    enum Type
    {
        Runtime,
        RuntimeNoCommandlet,
        Developer,
        Editor,
        EditorNoCommandlet,
        Program,
        Max,
    }
}


Ещё у модуля есть параметр LoadingPhase определяющий стадию загрузки модуля:
namespace ELoadingPhase
{
    enum Type
    {
        Default,
        PostDefault,
        PreDefault,
        PostConfigInit,
        PreLoadingScreen,
        PostEngineInit,
        Max,
    }
}


Любой модуль обязательно должен иметь 3 файла. Первый это заголовочный файл этого модуля <Имя модуля>.h, обычно в него включается файл Engine.h. Но стоит заметить что при включении файла Engine.h размер Precompiled header становится равен ~700mgb. Если вы создадите в своем проекте много модулей и каждый будет весить более 700mgb ни каких винчестеров не хватит, поэтому рекомендую открыть Engine.h и выбрать только то что вам надо. Кроме того в этом файле располагается интерфейс модуля. В котором можно что нибудь зарегистрировать например.

#pragma once

#include "Core.h"
#include "CoreUObject.h"
#include "Engine/EngineTypes.h"
#include "SlateCore.h"
#include "SlateBasics.h"
#include "ModuleManager.h"

DECLARE_LOG_CATEGORY_EXTERN(UICustomEditor, All, All)

class FUICustomEditorModule : public IModuleInterface
{
public:
        virtual void StartupModule() override;
        virtual void ShutdownModule() override;
};


Вторым обязательным файлом является файл .cpp:
#include "UICustomEditor.h"
#include "MyObjectAssetAction.h"
#include "MyStructCustomization.h"

DEFINE_LOG_CATEGORY(UICustomEditor)

void FUICustomEditorModule::StartupModule()
{
        FMyObjectAssetAction::RegistrateCustomPartAssetType();
        FMyClassDetails::RegestrateCostumization();
        UE_LOG(UICustomEditor, Warning, TEXT("Editor module Started"));
}

void FUICustomEditorModule::ShutdownModule()
{
        
        UE_LOG(UICustomEditor, Warning, TEXT("Editor module Stoped"));
}

IMPLEMENT_GAME_MODULE(FUICustomEditorModule, UICustom);


Здесь я регистрирую тип ассета и изменение панели свойств, а также добавил сообщение в лог.
В конце этого файла обязательно должен быть макрос IMPLEMENT_GAME_MODULE.

Третий обязательный файл <Имя модуля>.Build.cs:

using UnrealBuildTool;

public class UICustomEditor : ModuleRules
{
        public UICustomEditor(TargetInfo Target)
        {
                PublicDependencyModuleNames.AddRange(new string[] {
            "Core",
            "CoreUObject",
            "InputCore"
        });

        PrivateDependencyModuleNames.AddRange(new string[] {
            "Slate",
            "SlateCore",
            "PropertyEditor",
            "UnrealEd",
            "EditorStyle" });

        PrivateDependencyModuleNames.AddRange(new string[] { "GameLibPluginRuntime","UICustom" }); //Плагин и основной модуль
                
                
        }
}


В этом файле я подключаю модули необходимые для работы моего модуля (простите за тавтологию). Как видите кроме системных модулей я также подключил основной модуль и плагин(о котором я напишу ниже).

Важно: Если вы подключаете плагин к основному модулю то надо подключать его и к остальным. Иначе если вы используете объект из основного модуля в котором будет объект из плагина, то компилятор выдав ошибку о том что не может найти файл, сошлется на строчку в основном модуле но поскольку в нем вы плагин уже подключили вы не будете понимать в чем дело и что от вас требует компилятор.

Важно: Для того чтобы класс или структуру из подключенного модуля можно было использовать. Нужно:
1) Подключить заголовочный файл этого класса или структуры.
2) При определении классов и структур которые вы хотите использовать из других модулей нужно писать <имя модуля большими буквами>_API. Например:

class UICUSTOMEDITOR_API UMyObjectFactory : public UFactory

После создания этих файлов нужно положить их в папку с именем модуля в папке Source. Осталось только добавить наш модуль в файл UICustomEditor.Target.cs (в файл UICustom.Target.cs мы ни чего не добавляем поскольку модуль будет грузится только в редакторе)

OutExtraModuleNames.AddRange( new string[] { "UICustom", "UICustomEditor" } );

Модуль готов, для полезной нагрузки я использовал файлы из прошлого урока. Теперь перейдем к созданию плагина.

Создание плагина

Плагин нужно воспринимать как проект который можно вставить в другой проект. Плагин как и проект состоит из модулей и имеет свой файл проекта который имеет расширени .uplugin. Чтобы плагин подключить к проекту его надо положить в папку <директория проекта>/plugins и заново сгенерировать Visual Studio проект. После этого можно подключать модули плагина как и любые другие модули (об этом написано выше).

Соответственно для создания плагина нужно создать файл <Имя плагина>.uplugin

{
        "FileVersion" : 3,
        "FriendlyName" : "GameLibPlugin",
        "Version" : 48,
        "VersionName" : "1.0",
        "CreatedBy" : "Deema 35",
        "CreatedByURL" : " ",
        "EngineVersion" : "4.10.0",
        "Description" : "Library some system structure",
        "Category" : "System library",
        "EnabledByDefault" : true,
        "MarketplaceURL" : " ",
        
        "Modules" :
        [
                {
                        "Name" : "GameLibPluginRuntime",
                        "Type" : "Runtime",
                        "LoadingPhase" : "PreDefault"
                },
                {
                        "Name" : "GameLibPluginEditor",
                        "Type" : "Editor"
                }
        ],

        "CanContainContent" : true
}


Если в папке плагина создать папку Resources, то положенное туда изображение, в формате png будет отображаться в менеджере плагинов.
Далее в папке плагина/Source создаем папку для каждого из модулей плагина. Создание модулей плугина не отличается от создания модулей для проекта(о чем было написано выше). Собственно все плагин готов.
Для примера я сделал парсер CVS таблиц. После подключения плагина можно наблюдать:

image
image

Проект с исходным кодом: здесь

P.S Прошу учесть что я программист любитель, поэтому за кривость парсера просьба ногами не пинать.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Комментариев нет:

Отправить комментарий