首先,每个模块,包含插件内的模块在内,都要用IMPLEMENT_MODULE(类名, 模块名)的方式,模块名就是带.build.cs的第一个单词。
build.cs里就说了这个模块该怎么用,用c#编写。
打包中要考虑到target.cs,将工程中相应的模块打包进去
 uproject就要连插件和模块一起写进去
比如
 
这里,CoreOne和CoreTwo是工程里的多模块,myplugin和otherM是插件里的多模块。废话不多说,上代码
以工程中的一个模块CoreOne为例
coreOne.h
#pragma once
#include “CoreMinimal.h”
 #include “Modules/ModuleManager.h”
class FCoreOneModule : public FDefaultGameModuleImpl
 {
 public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
coreone.cpp
#include “CoreOne.h”
 #include “Modules/ModuleManager.h”
#define LOCTEXT_NAMESPACE “CoreOne”
void FCoreOneModule::StartupModule()
 {
 // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
 }
void FCoreOneModule::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.
 }
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCoreOneModule, CoreOne);
coreone.build.cs
 // Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class CoreOne : ModuleRules
 {
 public CoreOne(ReadOnlyTargetRules Target) : base(Target)
 {
 PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" });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
}
}
 再以插件中的一个模块otherM为例
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
 otherM.h
 #pragma once
#include “CoreMinimal.h”
 #include “Modules/ModuleManager.h”
class FOtherMModule : public IModuleInterface
 {
 public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
otherM.cpp
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include “OtherM.h”
#define LOCTEXT_NAMESPACE “OtherM”
void FOtherMModule::StartupModule()
 {
 // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
 }
void FOtherMModule::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.
 }
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FOtherMModule, OtherM)
otherM.build.cs
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class OtherM : ModuleRules
 {
 public OtherM(ReadOnlyTargetRules Target) : base(Target)
 {
 PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
    PublicIncludePaths.AddRange(new string[] {// ... add public include paths required here ...});PrivateIncludePaths.AddRange(new string[] {// ... add other private include paths required here ...});PublicDependencyModuleNames.AddRange(new string[]{"Core",// ... add other public dependencies that you statically link with here ...});PrivateDependencyModuleNames.AddRange(new string[]{"CoreUObject","Engine","Slate","SlateCore",// ... add private dependencies that you statically link with here ...	});DynamicallyLoadedModuleNames.AddRange(new string[]{// ... add any modules that your module loads dynamically here ...});
}
}
同样myplugin模块也是如此
 myplugin.h
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include “CoreMinimal.h”
 #include “Modules/ModuleManager.h”
class FMyPluginModule : public IModuleInterface
 {
 public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
myplugin.cpp
 // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include “MyPlugin.h”
#define LOCTEXT_NAMESPACE “FMyPluginModule”
void FMyPluginModule::StartupModule()
 {
 // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
 }
void FMyPluginModule::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.
 }
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FMyPluginModule, MyPlugin)
加上一个蓝图能调用的类,用以测试
DllTask.h
#pragma once
#include “CoreMinimal.h”
 #include “GameFramework/pawn.h”
 #include “DllTask.generated.h”
/**
 *
 */
 UCLASS(Blueprintable, BlueprintType)
 class MYPLUGIN_API ADllTask : public APawn
 {
 GENERATED_BODY()
public:
 UFUNCTION(BlueprintCallable, Category = “Dll”)
 void HelloDLL();
 };
DllTask.cpp
 #include “DllTask.h”
 #include <Engine.h>
 void ADllTask::HelloDLL()
 {
 if (GEngine)
 {
 GEngine->AddOnScreenDebugMessage(-1, 200.0f, FColor::Blue, TEXT(“Hello Dll”));
 }
 }
 PluginTest.Target.cs
 // Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
 using System.Collections.Generic;
public class PluginTestTarget : TargetRules
 {
 public PluginTestTarget(TargetInfo Target) : base(Target)
 {
 Type = TargetType.Game;
	ExtraModuleNames.AddRange( new string[] { "PluginTest", "CoreOne", "CoreTwo" } );
}
}
 PluginTestEditor.Target.cs
 // Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
 using System.Collections.Generic;
public class PluginTestEditorTarget : TargetRules
 {
 public PluginTestEditorTarget(TargetInfo Target) : base(Target)
 {
 Type = TargetType.Editor;
	ExtraModuleNames.AddRange( new string[] { "PluginTest", "CoreOne", "CoreTwo" } );
}
}
 PluginTest.uproject
{
 “FileVersion”: 3,
 “EngineAssociation”: “4.22”,
 “Category”: “”,
 “Description”: “”,
 “Modules”: [
 {
 “Name”: “PluginTest”,
 “Type”: “Runtime”,
 “LoadingPhase”: “Default”
 },
 {
 “Name”: “CoreOne”,
 “Type”: “Runtime”,
 “LoadingPhase”: “Default”
 },
 {
 “Name”: “CoreTwo”,
 “Type”: “Runtime”,
 “LoadingPhase”: “Default”
 }
 ],
“Plugins”: [
 {
 “Name”: “MyPlugin”,
 “Enabled” : true
 }
 ]
 }
现在编辑器里试验下
 设置默认地图为newmap
 
 将dlltask拖进场景
 
打开关卡蓝图测试
 
 运行正常
 
 现在开始打包,先烘培
 
 
 再打包64位windows
 
 
 
 找到打包位置,双击打开
 
 
 ok