日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

[UE4C++程序]GameModule与Plugin

發(fā)布時(shí)間:2024/1/8 c/c++ 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [UE4C++程序]GameModule与Plugin 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)專(zhuān)案建立的時(shí)候,引擎會(huì)自動(dòng)產(chǎn)生一個(gè)同名的Game Module在Source資料夾底下。我們當(dāng)然可以將所有撰寫(xiě)的C++類(lèi)別全部放在這個(gè)Module中,可是當(dāng)專(zhuān)案越來(lái)越大,若還是將所有的功能都放在同個(gè)Module下,不僅僅會(huì)造成管理上的混亂,而且編譯時(shí)間也會(huì)增加。

試著想像當(dāng)我們隨便改動(dòng)一個(gè)h檔或cpp檔的參數(shù)就要編譯幾10分鐘的情況?由于UE4在一個(gè)Module中的cpp數(shù)量到達(dá)32個(gè)的時(shí)候就會(huì)自動(dòng)啟動(dòng)編譯檔案合并的機(jī)制(Unity Build),雖然UE4中有參數(shù)可以控制這個(gè)機(jī)制是否啟用,但卻是舍棄掉了整體的編譯時(shí)間。因此,如何將功能適當(dāng)?shù)那械礁鲃eModule中,就變成了一件非常重要的程式架構(gòu)設(shè)計(jì)問(wèn)題。

那么實(shí)際上UE4的Module系統(tǒng)是怎么運(yùn)作的呢?

每一個(gè)獨(dú)立的Module基本上是由${MODULE_NAME}.build.cs與其下的C++程式碼所組成,而在UE4中,游戲中的Module主要被分成以下幾種實(shí)作Macro定義:

  • IMPLEMENT_PRIMARY_GAME_MODULE
  • IMPLEMENT_GAME_MODULE
  • IMPLEMENT_MODULE

到底這些實(shí)作彼此之間有什么不同?

其實(shí),這些Macro定義在最后都會(huì)被展開(kāi)成IMPLEMENT_MODULE中的實(shí)作,它們之間在本質(zhì)上并沒(méi)有不同,主要是用提供Module初始化Function的實(shí)作給UE4中的ModuleManager呼叫,參照Code 2.4.1:

  • #define IMPLEMENT_PRIMARY_GAME_MODULE ( ModuleImplClass, ModuleName , GameName ) \
  • IMPLEMENT_GAME_MODULE ( ModuleImplClass, ModuleName )
  • ?
  • ?
  • ?
  • #define IMPLEMENT_GAME_MODULE ( ModuleImplClass, ModuleName ) \
  • ?
  • IMPLEMENT_MODULE ( ModuleImplClass, ModuleName )
  • ?
  • ?
  • ?
  • #define IMPLEMENT_MODULE ( ModuleImplClass, ModuleName ) \
  • ?
  • extern “C" DLLEXPORT IModuleInterface * InitializeModule () \
  • ?
  • { \
  • ?
  • return new ModuleImplClass(); \
  • ?
  • } \
  • ?
  • PER_MODULE_BOILERPLATE \
  • ?
  • PER_MODULE_BOILERPLATE_ANYLINK (ModuleImplClass, ModuleName )
  • ?

    Code 2.4.1 Module的定義Macro,最后都會(huì)被展開(kāi)成IMPLEMENT_MODULE中的實(shí)作。其中PER_MODULE_BOILERPLATE讓引擎有機(jī)會(huì)提供一些額外的功能給這個(gè)module,例如把原本C++中的New跟delete做Overriding,并將功能導(dǎo)向UE4中的記憶體管理機(jī)制。最后的PER_MODULE_BOILERPLATE_ANYLINK其實(shí)并沒(méi)有其他特別的功能,就只是用來(lái)做標(biāo)示,用來(lái)說(shuō)明這個(gè)Module相關(guān)的定義已經(jīng)完成。

    從上面的程式碼中我們可以看出,從Primary Game Module、Game Module到Module總共有三個(gè)層級(jí)的定義。只是,既然這些Module的定義做的事情都差不多,那為何引擎還要個(gè)別提供?

    這邊雖然沒(méi)辦法完全的掌握設(shè)計(jì)者的意圖,但至少我們可以推敲出區(qū)分出這些Module定義名稱(chēng)的好處:若以后想要在Primary Game Module或Game Module層級(jí)增加功能的時(shí)候,就不會(huì)影響到最下層的Module層級(jí)的實(shí)作。

    到這里,或許有人會(huì)開(kāi)始思考這幾個(gè)層級(jí)到底應(yīng)該用在哪些地方。其實(shí)UE4在架構(gòu)上把程式碼拆分成以下幾個(gè)部份:

    • Engine:位于${UE4_ENGINE_ROOT}/Engine/Source/下面的Developer、Editor、Runtime以及ThirdParty這幾個(gè)資料夾。
    • Engine Plugin:位于${UE4_ENGINE_ROOT}/Engine/Plugin/。
    • Game:位于${PROJECT_NAME}/Source/。
    • Game Plugin:位于${PROJECT_NAME}/Plugin/。
    • Programs:位于${UE4_ENGINE_ROOT}/Engine/Source/Programs,屬于獨(dú)立運(yùn)行的工具類(lèi)程式,里面使用C#或C++分別進(jìn)行不同的實(shí)作。

    其中只有位于Game中的Module會(huì)使用IMPLEMENT_PRIMARY_GAME_MODULE跟IMPLEMENT_GAME_MODULE這2個(gè)實(shí)作,從名稱(chēng)中我們可以推測(cè)出,作為主要游戲的入口的Primary Game Module只能有一個(gè),其他則都必需設(shè)成Game Module。

    其他在Engine、Engine Plugin跟Game Plugin底下的Module則都是直接使用IMPLEMENT_MODULE這個(gè)定義。

    當(dāng)然,就目前的引擎版本我們是可以全部都用IMPLEMENT_MODULE來(lái)實(shí)作出上面Module所有效果,但是為了往后更新引擎版本時(shí)的兼容性,建議還是照著UE4所定義出來(lái)的流程實(shí)作。

    最后的Programs跟其他的Module不同,里面的C++ Module會(huì)使用IMPLEMENT_APPLICATION這個(gè)定義,參見(jiàn)Code 2.4.2。

  • #if IS_MONOLITHIC
  • ?
  • ?
  • #define IMPLEMENT_APPLICATION ( ModuleName , GameName ) \
  • ?
  • /* For monolithic builds, we must statically define the game's name string (See Core.h) */ \
  • ?
  • TCHAR GInternalGameName [64] = TEXT ( GameName ); \
  • ?
  • IMPLEMENT_DEBUGGAME () \
  • ?
  • IMPLEMENT_FOREIGN_ENGINE_DIR () \
  • ?
  • IMPLEMENT_GAME_MODULE ( FDefaultGameModuleImpl , ModuleName ) \
  • ?
  • PER_MODULE_BOILERPLATE \
  • ?
  • FEngineLoop GEngineLoop ;
  • ?
  • ?
  • ?
  • #else
  • ?
  • ?
  • ?
  • #define IMPLEMENT_APPLICATION ( ModuleName , GameName ) \
  • ?
  • /* For non-monolithic programs, we must set the game's name string before main starts (See Core.h) */ \
  • ?
  • struct FAutoSet##ModuleName \
  • ?
  • { \
  • ?
  • FAutoSet##ModuleName() \
  • ?
  • { \
  • ?
  • FCString :: Strncpy ( GInternalGameName , TEXT ( GameName ), ARRAY_COUNT ( GInternalGameName )); \
  • ?
  • } \
  • ?
  • } AutoSet##ModuleName; \
  • ?
  • PER_MODULE_BOILERPLATE \
  • ?
  • PER_MODULE_BOILERPLATE_ANYLINK ( FDefaultGameModuleImpl , ModuleName ) \
  • ?
  • FEngineLoop GEngineLoop ;
  • ?
  • ?
  • ?
  • #endif
  • ?

    Code 2.4.2 在UE4中,Module的Link分成Modular跟Monolithic二種方式:Modular指的是將Module編譯成各別的dynamic library再做連結(jié);Monolithic則是指將所有的Module全部編譯到同一份Library中。其中Editor預(yù)設(shè)是Modular,而Game預(yù)設(shè)是Monolithic。

    而要不要把該Module放到Plugin或者是當(dāng)成Game Module,則要看這個(gè)Module需不需要用在不同的專(zhuān)案上使用。若是這個(gè)Module中的功能需要讓其他專(zhuān)案使用的話(huà),則將該Module制作成Plugin會(huì)比單純的當(dāng)成Game Module會(huì)更有彈性。

    ?

    ?

    • 在UE項(xiàng)目添加一個(gè)新的Module

    本文只簡(jiǎn)單介紹下創(chuàng)建自定義模塊的方法

    1. 新建項(xiàng)目并在Source文件夾下建立我們要添加的新模塊?
    ?
    2. 并在新建的NewModule文件夾下創(chuàng)建.h .cpp .Build.cs 后綴的3個(gè)文件?
    ?
    3.?進(jìn)入VS建立NewModule(篩選器)并把剛才文件夾里新創(chuàng)建的3個(gè)文件拖入NewModule下?
    ?
    4.為NewModule.Build.cs添加內(nèi)容(直接從我們項(xiàng)目里的TestModule.Build.cs拷貝即可)?

    using UnrealBuildTool;

    public class NewModule: ModuleRules
    {
    ? ? public NewModule(ReadOnlyTargetRules Target) : base(Target)
    ?? ?{
    ? ? ? ? PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

    ? ? ? ? PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

    ? ? ? ? PrivateDependencyModuleNames.AddRange(new string[] { });

    ? ? ? ? // Uncomment if you are using Slate UI
    ? ? ? ? // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

    ? ? ? ? // Uncomment if you are using online features
    ? ? ? ? // PrivateDependencyModuleNames.Add("OnlineSubsystem");

    ? ? ? ? // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    ? ? }
    }

    5. 修改NewModule.h為

    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "Engine.h"
    #include "ModuleManager.h"

    class FNewModuleModule : public IModuleInterface
    {
    public:

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

    ?

    6.修改NewModule.cpp為

    // Copyright Sigurdur Gunnarsson. All Rights Reserved.?
    // Licensed under the MIT License. See LICENSE file in the project root for full license information.?

    #include "NewModule.h"

    void FNewModuleModule::StartupModule()
    {
    ? // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
    }

    void FNewModuleModule::ShutdownModule()
    {
    ? // This function may be called during shutdown to clean up your module. ?For modules that support dynamic reloading,
    ? // we call this function before unloading the module.
    }

    ??
    IMPLEMENT_MODULE(FNewModuleModule, NewModule)

    6. 進(jìn)入項(xiàng)目的uproject內(nèi)添加我們的新模塊?
    ?
    7. 最后在項(xiàng)目里的.Target.cs里添加新的模塊名?

    2個(gè).Target.cs后綴的都需要添加模塊名?


    8. 使用Editor在NewModule下創(chuàng)建Actor,重新編譯成功后,在C++ Class下就能看到新建的NewModule
    ?
    ?

    總結(jié)

    以上是生活随笔為你收集整理的[UE4C++程序]GameModule与Plugin的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。