ARTICLE · 1125281
在 UE4 插件中集成并调用第三方库

在 UE4 插件中集成并调用第三方库
在 UE4 开发中,集成第三方库(如物理引擎、音频处理库、网络库等)是常见的需求。UE4 提供了完善的插件机制,通过创建自定义插件,可以优雅地将第三方库封装并暴露给项目使用。本文将系统讲解整个流程,并给出可运行的代码示例。
一、整体思路
UE4 插件调用第三方库的核心步骤:
创建插件目录结构 放置第三方库(源码 / 静态库 / 动态库) 编写 .Build.cs配置库路径与链接在 Public中声明接口在 Private中实现调用注册插件并在项目中使用
⚠️ 注意:UE4 插件的构建配置使用 C# 编写的
.Build.cs文件,而不是 Gradle(Gradle 是 Android 或某些自定义构建系统使用的)。原文中提到的PluginBuild.gradle是误解,正确文件是*.Build.cs。
二、创建插件目录
在项目根目录下创建:
MyProject/
└── Plugins/
└── MyThirdPartyPlugin/
├── MyThirdPartyPlugin.uplugin
├── Source/
│ └── MyThirdPartyPlugin/
│ ├── MyThirdPartyPlugin.Build.cs
│ ├── Public/
│ │ └── MyThirdPartyPlugin.h
│ └── Private/
│ ├── MyThirdPartyPlugin.cpp
│ └── ThirdParty/
│ ├── include/
│ │ └── MyLib.h
│ └── lib/
│ └── Win64/MyLib.lib
└── Resources/
MyThirdPartyPlugin.uplugin
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "My Third Party Plugin",
"Description": "Integrates MyLib into UE4",
"Category": "Other",
"CreatedBy": "YourName",
"CanContainContent": true,
"Modules": [
{
"Name": "MyThirdPartyPlugin",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}
三、配置第三方库(.Build.cs)
假设第三方库是一个静态库 MyLib.lib,头文件在 include/,库在 lib/Win64/。
MyThirdPartyPlugin.Build.cs
using UnrealBuildTool;
using System.IO;
publicclassMyThirdPartyPlugin : ModuleRules
{
publicMyThirdPartyPlugin(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(newstring[]
{
"Core",
"CoreUObject",
"Engine"
});
// 第三方库根目录
string ThirdPartyPath = Path.Combine(ModuleDirectory, "Private", "ThirdParty");
// 头文件路径
PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));
// 链接库
if (Target.Platform == UnrealTargetPlatform.Win64)
{
string LibPath = Path.Combine(ThirdPartyPath, "lib", "Win64");
PublicAdditionalLibraries.Add(Path.Combine(LibPath, "MyLib.lib"));
}
elseif (Target.Platform == UnrealTargetPlatform.Linux)
{
string LibPath = Path.Combine(ThirdPartyPath, "lib", "Linux");
PublicAdditionalLibraries.Add(Path.Combine(LibPath, "libMyLib.a"));
}
// 如果是动态库,需要拷贝并延迟加载
// string DllPath = Path.Combine(LibPath, "MyLib.dll");
// RuntimeDependencies.Add("$(BinaryOutputDir)/MyLib.dll", DllPath);
// PublicDelayLoadDLLs.Add("MyLib.dll");
}
}
四、声明接口(Public 头文件)
Public/MyThirdPartyPlugin.h
#pragma once
#include"CoreMinimal.h"
#include"Modules/ModuleManager.h"
// 对外暴露的接口类
classMYTHIRDPARTYPLUGIN_APIFMyThirdPartyPlugin
{
public:
static FMyThirdPartyPlugin& Get();
/** 调用第三方库的加法函数 */
int32 AddNumbers(int32 A, int32 B);
/** 调用第三方库的字符串处理函数 */
FString ToUpper(const FString& Input);
private:
FMyThirdPartyPlugin() = default;
};
// 模块定义(可选,供引擎加载使用)
classFMyThirdPartyPluginModule :public IModuleInterface
{
public:
virtualvoidStartupModule()override;
virtualvoidShutdownModule()override;
};
五、实现接口(Private 源文件)
Private/MyThirdPartyPlugin.cpp
#include"MyThirdPartyPlugin.h"
// 第三方库的 C 接口头文件
extern"C"
{
#include"MyLib.h"// 假设提供 int mylib_add(int, int); 和 const char* mylib_toupper(const char*);
}
#define LOCTEXT_NAMESPACE "FMyThirdPartyPluginModule"
// ---------------- 单例 ----------------
FMyThirdPartyPlugin& FMyThirdPartyPlugin::Get()
{
static FMyThirdPartyPlugin Instance;
return Instance;
}
// ---------------- 接口实现 ----------------
int32 FMyThirdPartyPlugin::AddNumbers(int32 A, int32 B)
{
// 调用第三方 C 函数
return mylib_add(A, B);
}
FString FMyThirdPartyPlugin::ToUpper(const FString& Input)
{
// FString -> std::string -> C 字符串
std::string StdInput = TCHAR_TO_UTF8(*Input);
constchar* Result = mylib_toupper(StdInput.c_str());
return FString(UTF8_TO_TCHAR(Result));
}
// ---------------- 模块加载 ----------------
voidFMyThirdPartyPluginModule::StartupModule()
{
UE_LOG(LogTemp, Log, TEXT("MyThirdPartyPlugin module started."));
}
voidFMyThirdPartyPluginModule::ShutdownModule()
{
UE_LOG(LogTemp, Log, TEXT("MyThirdPartyPlugin module shutdown."));
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FMyThirdPartyPluginModule, MyThirdPartyPlugin)
假设的第三方头文件 include/MyLib.h
#ifndef MYLIB_H
#define MYLIB_H
#ifdef __cplusplus
extern"C" {
#endif
intmylib_add(int a, int b);
constchar* mylib_toupper(constchar* input);
#ifdef __cplusplus
}
#endif
#endif
六、在项目中启用插件
打开 UE4 编辑器 → Edit → Plugins → 搜索 MyThirdPartyPlugin→ 勾选启用。重新生成项目文件(右键 .uproject→ Generate Visual Studio project files)。编译项目。
七、在游戏代码中调用
在任意 Actor 或 GameMode 中:
#include"MyThirdPartyPlugin.h"
voidAMyActor::BeginPlay()
{
Super::BeginPlay();
// 获取插件单例
FMyThirdPartyPlugin& Plugin = FMyThirdPartyPlugin::Get();
int32 Sum = Plugin.AddNumbers(3, 5);
FString Upper = Plugin.ToUpper(TEXT("hello ue4"));
UE_LOG(LogTemp, Log, TEXT("Sum=%d, Upper=%s"), Sum, *Upper);
}
输出:
LogTemp: Sum=8, Upper=HELLO UE4
八、常见问题与调试
PublicAdditionalLibraries 路径 | ||
PublicIncludePaths 或 PrivateIncludePaths | ||
RuntimeDependencies.Add | ||
Build.cs 中按 Target.Platform 分别配置 | ||
extern "C" 包装,且只在 .cpp 中包含 |
调试建议
使用 Development Editor 配置,日志更详细。 在 Build.cs中可加入:bEnableExceptions = true; // 若第三方库抛异常
bUseRTTI = true; // 若库使用 RTTI使用 UE_LOG打印调用前后状态,定位问题。
九、跨平台与版本管理
跨平台:
if (Target.Platform == UnrealTargetPlatform.Win64) { /* .lib */ }
elseif (Target.Platform == UnrealTargetPlatform.Linux) { /* .a */ }
elseif (Target.Platform == UnrealTargetPlatform.Mac) { /* .dylib */ }
elseif (Target.Platform == UnrealTargetPlatform.Android) { /* .so */ }
版本控制:
将插件源码、第三方头文件、库文件一并纳入 Git。 使用 Git LFS 管理 .lib/.dll/.so等二进制文件。在 .gitattributes中声明:*.lib filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
十、总结
*.uplugin | |
*.Build.cs | |
Public/*.h | |
Private/*.cpp | |
IMPLEMENT_MODULE | |
FMyThirdPartyPlugin::Get() |
通过上述流程,你可以将任意第三方 C/C++ 库无缝集成进 UE4 项目。核心要点是:
.Build.cs是唯一构建入口(不是 Gradle);头文件隔离,避免污染引擎命名空间; 按平台分别配置,保证跨平台可编译; 统一封装接口,游戏逻辑只依赖插件公开 API。
持续维护插件,跟进 UE4/UE5 引擎升级与第三方库版本,可以让你的项目长期稳定获益。