大家好,又见面了,我是你们的朋友全栈君。
UE4插件研发
UE4插件扫盲
UE4插件是什么
UE4引擎和UE4项目是由各个模块组成的,其主要编程语言是C++。
插件也是一个模块,说到插件必须讲到耦合性与独立性,耦合性是对模块间关联程度的度量,模块间关联越强,则耦合性强,独立性差。
庞大的UE4引擎各模块相互参差作用,所以想要读懂并拆解并非易事,而创建UE4游戏项目实则只引入了引擎的部分模块,再想想如果很多游戏项目都需要用到这一个自定义功能时,是不是每个项目都要开发一次这个功能,个人或者一家公司内部还好,只要把项目代码复制给另一个项目即可,但是全球这么多的UE4开发者怎么办,开发者的结晶势必要发挥它最大的用处,把自己的研发成果分享出去,为了解决这类问题,就要使得模块独立起来,那么UE4插件就该闪亮登场了。
UE4插件的作用
举个栗子:两个人同时在设计创建机器人,A为自己的机器人造了一把枪,B却为自己的机器人造了飞行器,AB两人把自己的成果分享出来,于是高达诞生了。
UE4引擎拥有插件管理模块并提供了插件加载卸载和其他功能接口,所以UE4插件可以自定义功能,因为其独立性强可以发布共享,且使用方便。
UE4引擎、项目、插件的区别
UE4引擎由Epic官方维护与发布,源码托管在GitHub平台上,可以上官网下载EpicGamesLauncher管理下载各个UE4 Release版本。
UE4项目是基于某个版本而创建的Game项目,在Game项目中可以设计关卡、摆放场景、添加功能、发布应用程序等,发布后可以脱离引擎独立运行。
UE4插件可以增加UE4的扩展性,丰满Game项目,也可让开发应用程序变得简单且多样化,但其不能独立运行。
引擎自带的插件浏览器
UE4插件管理界面中的插件对应了UE4安装目录下的Plugins文件下的插件,列表类目名有些和文件夹名字对应不上,那是因为类目名由插件项目.uplugin文件中的Category字段内容来生成的。
1. UE4插件浏览器界面
2. UE4安装目录插件文件夹
插件目录结构
假如创建一个游戏项目叫PluginFactory,在这个游戏项目来创建一个名为PanoCam的插件则插件目录如下
- PluginFactory
- Plugins
- PanoCam
- Binaries
- Content
- Intermediate
- Resources
- Source
- PanoCam
- Private
- PanoCam.cpp
- Public
- PanoCam.h
- PanoCam.Build.cs
- Private
- PanoCam
- PanoCam.uplugin
- PanoCam
- Plugins
Binaries:编译后的dll文件存放位置
Content:游戏资源Asset文件存放位置
Intermediate:编译的中间文件存放位置
Resources:一般为图片图标的存放位置
Source:代码存放位置
.uplugin文件:插件项目配置文件,JSON格式
.Build.cs文件:每个 .build.cs 文件声明派生自 ModuleRules 基类的类,并设置属性控制器从构造函数进行编译的方式。由虚幻编译工具编译,并被构造来确定整体编译环境。使用C#语法
插件配置文件说明
1. uplugin文件
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "PanoCam",
"Description": "",
"Category": "Other",
"CreatedBy": "Scrat",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"Installed": true,
"Modules": [
{
"Name": "PanoCam",
"Type": "Runtime",
"LoadingPhase": "PreDefault",
"WhitelistPlatforms": [
"Win32",
"Win64"
]
}
]
}
几个重点注意的标签
- Category:类目名即在插件浏览器中所属的类目。
- Installed:默认启用或禁用状态,在插件浏览器中可以控制加载卸载插件模块。
- Modules:描述模块名、运行类型、加载时机、支持平台等信息。
- Type:Runtime,RuntimeNoCommandlet,Developer,Editor,EditorNoCommandlet,Program。
- LoadingPhase:Default,PreDefault,PostConfigInit,PostConfigInit。
- WhitelistPlatforms:支持的平台
- BlacklistPlatforms:不支持的平台
2. Build.cs文件
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class PanoCam : ModuleRules
{
public PanoCam(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
"PanoCam/Public"
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
"PanoCam/Private",
// ... 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 ...
}
);
}
}
配置文件中的属性说明
- public class PanoCam : ModuleRules 中的PanoCam为模块名,代码引用中认准这个名字
- PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs
预编译标头使用显示或共享标头。 - PublicIncludePathModuleNames (List)
带有标头文件的模块名称列表(无需路径),需要由模块的公共标头访问,但不需要再“导入”或链接。 - PublicDependencyModuleNames (List)
公共依赖性模块名称列表(不需要路径)(自动包含私有/公共)。这些是公共源文件所需的模块。 - PrivateIncludePathModuleNames (List)
带有标头文件的模块名称列表(无需路径),需要由模块的私有代码文件访问,但不需要再“导入”或链接。 - PrivateDependencyModuleNames (List)
私有依赖性模块名称列表。这些是私有代码所依赖的模块,但公共include文件中没有任何依赖。 - DynamicallyLoadedModuleNames (List)
此模块在运行时可能需要的附加模块。 - PublicSystemIncludePaths (List)
系统/库include路径列表,通常用于外部(第三方)模块。在解析标头依赖项时未检查的公共稳定标头文件目录。 - PublicIncludePaths (List)
(当前不需要此设置,因为可以从“Public”文件夹中搜索所有文件)公开给其他模块的include文件的所有路径列表。 - PrivateIncludePaths (List)
此模块内部include文件的所有路径的列表,未公开给其他模块(至少有一个包含在“私有”路径中,如果要避免相对路径,可以添加更多) - PublicLibraryPaths (List)
系统/库路径列表(.lib文件的目录),通常用于外部(第三方)模块。 - PublicAdditionalLibraries (List)
其他库的列表(包括扩展名的.lib文件的名称),通常用于外部(第三方)模块。
Build.cs配置文件一个重要技巧
如果插件中有依赖非UAsset文件,打包时需要手动拷贝到打包对应路径下,使用一下方法可使其自动拷贝过去
using UnrealBuildTool;
using System.IO;
public class PanoCam : ModuleRules
{
//封装一个函数专门获取依赖文件的路径
private string ContentSlatePath
{
get { return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../Content/Slate/")); }
}
public PanoCam(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
//遍历路径下的文件,通过RuntimeDependencies来添加运行时依赖文件
if (Directory.Exists(ContentSlatePath))
{
foreach (string Picture in Directory.EnumerateFiles(ContentSlatePath, "*.*", SearchOption.AllDirectories))
{
RuntimeDependencies.Add(Path.Combine(ContentSlatePath, Picture));
}
}
}
}
UE4插件的创建方法
开发环境:Windows、UE4.21、VistualStudio2017
前提:必须创建一个UE4 C++项目
插件创建有三种方法:
1.使用UE4自带的插件创建方法
2.自己手动创建插件目录及相关配置与代码文件
手动创建后需要在UE4项目的.uproject文件上右键执行Generate Vistual Studio project files来刷新代码目录结构,如果只是添加或删减少量文件的话此步骤也可以手动在VistualStudio中操作。
3.写一个插件生成插件
创建一个插件,并在插件中设置自定义的插件模板文件,在插件功能中复制对应的自定义插件模板文件到项目插件目录中,并动态修改文件夹名和文档关键字即可实现自定义插件生成器。
插件代码的执行过程
PanoCam.h的代码内容如下
#pragma once
#include "CoreMinimal.h"
#include "ModuleManager.h"
class FPanoCamModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
每个独立模块都有一个这样的类且继承于 IModuleInterface,重写了插件加载卸载的方法。
.uplugin文件中Modules下的LoadingPhase字段说明了模块加载的时机,当满足这个时机时此模块StartupModule函数将被调用。
此插件的功能入口就是从这里开始。
当程序关闭或主动调用ShutdownModule函数时,模块将被卸载。
四种常用模式的插件模板
- Blank
空白模板,最简洁的结构,只有模块类和加载卸载函数,一张白纸最好作画了。 - BlueprintLibrary
蓝图功能库模板,都是静态函数,提供给蓝图直接调用的,如果只是单一的功能集的话,用此模板最快捷 - EditorToolbarButton
编辑器工具栏按钮模板,此模板在模块加载时会在UE4编辑器工具栏中注册一个按钮,点击此按钮将触发插件模块中的PluginButtonClicked函数。 - EditorStandaloneWindow
编辑器独立窗口模板,顾名思义,它将创建出一个窗口,可以在此窗口中自定义界面,像引擎编辑器的各个界面一样的效果。
第三方库的引入
UE4模块引入第三方库,只要在Build.cs中配置头文件路径及添加lib文件即可。
以zlib为例,在.uplugin同级创建ThirdParty文件夹,把第三方库文件放在其中,此处为了节省篇幅只展示一条全路径zlib/v1.2.8/include/Win64/VS2015/。
此第三方库zlib引擎自带,可根据自己的引擎安装目录获取到(如:E:\Program Files\Epic Games\UE_4.21\Engine\Source\ThirdParty\zlib),我也上传了一份到csdn资源中可供单独下载使用。
目录结构如下。
- plugins
- PanoCam
- Source
- PanoCam.uplugin
- ThirdParty
- zlib
- v1.2.8
- lib
- include
- Win32
- Win64
- VS2015
- zconf.h
- zlib.h
- VS2015
- v1.2.8
- zlib
- PanoCam
重新编辑Build.cs代码,引入第三方库zlib
using UnrealBuildTool;
public class PanoCam : ModuleRules
{
public PanoCam(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
//~~~和之前一样,此处代码不变
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
//此处开始配置第三方库zlib
string zlibPath = ModuleDirectory + "../ThirdParty/zlib/v1.2.8/";
if (Target.Platform == UnrealTargetPlatform.Win64)
{
string platform = "/Win64/VS2015";
PublicIncludePaths.Add(zlibPath + "include" + platform);
PublicLibraryPaths.Add(zlibPath + "lib" + platform);
PublicAdditionalLibraries.Add("zlibstatic.lib");
}
else if (Target.Platform == UnrealTargetPlatform.Win32)
{
string platform = "/Win32/VS2015";
PublicIncludePaths.Add(zlibPath + "include" + platform);
PublicLibraryPaths.Add(zlibPath + "lib" + platform);
PublicAdditionalLibraries.Add("zlibstatic.lib");
}
}
}
虽然添加了十几行代码,但重要的代码就三行
- PublicIncludePaths.Add(zlibPath + “include” + platform); //此行是把(.h)头文件路径引入。
- PublicLibraryPaths.Add(zlibPath + “lib” + platform); //此行是把(.lib)库文件路径引入。
- PublicAdditionalLibraries.Add(“zlibstatic.lib”); //此行是把(.lib)库文件引入。
之后就可以在你的代码中#include 第三方的(.h)文件,使用其中的功能了。
牛刀小试
创建Actor到视图插件
- 新建UE4 C++项目。
- 在UE4编辑器菜单栏Edit中打开Plugins。
- 新建插件,模板选择Editor Toolbar Button,插件名随意。
- VS项目会自动加载刷新,目录结构如下
- 在TestToolbar.cpp添加代码
//添加头文件
#include "LevelEditorViewport.h"
#include "Engine/StaticMeshActor.h"
//修改PluginButtonClicked函数代码
void FTestToolbarModule::PluginButtonClicked()
{
//通过当前编辑视图实例获取当前World
UWorld *World = GCurrentLevelEditingViewportClient->GetWorld();
if (World)
{
//在视图中放置StaticMeshActor
AStaticMeshActor* Actor = World->SpawnActor<AStaticMeshActor>(FVector(0, 0, 100), FRotator::ZeroRotator);
//加载引擎Asset资源
UStaticMesh* ConeMesh = LoadObject<UStaticMesh>(NULL, TEXT("/Engine/BasicShapes/Cone.Cone"), NULL, LOAD_None, NULL);
UMaterial* Mat = LoadObject<UMaterial>(NULL, TEXT("/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial"), NULL, LOAD_None, NULL);
if (ConeMesh)
{
//设置Mesh材质
ConeMesh->SetMaterial(0, Mat);
//设置MeshComponent的Mesh
Actor->GetStaticMeshComponent()->SetStaticMesh(ConeMesh);
}
//刷新编辑中的视图,如果不加这行,则需要鼠标触发一下视图,视图才会刷新
GEditor->RedrawLevelEditingViewports(true);
}
}
- 编译后启动项目。
- 点击工具栏中新注册的按钮即可。
熟悉引擎架构,利用好UE4 API可以在创造出无限可能,有好的东西自然要懂得分享,小时候妈妈经常这样教导我们,那么试试发布你的插件吧。
插件打包
- 打包插件之前需要先确保声明插件所支持的平台(参考上面.uplugin文件配置说明内容)
"WhitelistPlatforms": [ "Win32", "Win64" ]
- 在UE4插件管理页面中打包插件
- 控制台命令行使用批处理工具打包插件
"E:\Program Files\Epic Games\UE_4.25\Engine\Build\BatchFiles\RunUAT.bat" BuildPlugin Plugin="D:\work\UE4_25\PluginFactory\Plugins\MyNewPlugin\MyNewPlugin.uplugin" Package="D:\work\UE4_25\PluginPackaged"
- 不带源码发布
- 纯蓝图项目
删除插件的Intermediate和Source文件夹中的Public和Private文件夹,只保留.Build.cs文件,修改.uplugin文件//部分省略 ,需添加 "EnabledByDefault": false,否则启动打包程序运行将失败 "EnabledByDefault": false, "Installed": true,
- C++项目
删除插件Source文件夹中的Public和Private文件夹,只保留.Build.cs文件,需要修改.Build.cs文件内容//若存在bPrecompile = true; 则替换成bUsePrecompiled = true; //否则添加bUsePrecompiled = true;
不然其他C++项目使用此插件会重编译插件失败,若编译项目后放置插件虽然能在编辑器上使用但打包会报错,报错提示需要设置这么一个东西:PrecompileForTargets = PrecompileTargetsType.None
插件发布
插件发布是指把你开发的插件分享出去给其他人使用,这时候有几个地方要注意
- 插件发布到哪里?(别人从哪里获取你的插件文件?)
如果是公司内部则好办,文件传输或者公司自己的资源平台即可
如果是发布到UE4官方商城,则需要进入www.unrealengine.com查阅虚幻商城指南,大致流程如下:- 注册Epic账号并登陆。
- 进入发布者门户(Publisher Portal)
- 申请成为UE4商城卖家主要有5步,需要添加必要信息。
- PUBLISHER INFO(商家信息): 必须填写手机号
- STORE INFO(商店信息):此处可以直接下一步
- PAYOUT INFO(支付信息):使用PayPal或者银联卡
- TAX INFO(税收信息):国家 – 中国、I Report Tax Outside Of The United States、NameOnTaxID – 0、Individual/Sole Proprietor、地址信息······。
- OPEN SHOP(开张)
- 编辑商品信息。
- 提交商品表单,官方会在一定时间内审核。
- 插件编译版本
用户使用插件时的UE4版本需要与插件编译时的UE4版本一致,不然会警告提示版本不一致而丢失插件。
所以发布插件时要注明插件所支持的UE4版本号。 - 插件平台支持
同上,如果插件支持Win32和Win64 或是 Mac 或是Android,发布时也需要注明。 - 插件运行类型
.uplugin文件中的Module标签下的Type标签表明了插件运行类型,如果不是Runtime则不是运行在打包后的Game中,Developer或Editor等其他值可查阅官方资料。 - 插件更新机制
如有平台支持,可设计更新机制,开发过程复杂,此处跳过
常见的问题
- 增删代码时,没有更新VistualStudio项目(uproject文件上右键点击Generate Vistual Studio project files可更新重载项目代码)
- .Build.cs代码语法错误导致编译错误。
- 第三方库路径配置错误,导致引入失败,头文件找不到或者链接lib文件失败。
- 引擎版本与插件版本不一致导致插件模块丢失不能使用。
- 插件的”Installed”: false,或者插件浏览器中没有启动插件,导致插件模块没有找到。
- 插件的Module下的”Type”配置与实际项目运行类型不一致。
- .插件的Module下的”LoadingPhase”配置与项目实际使用插件模块时机不一致,导致插件模块没有找到。
- uplugin内容语法错误导致启动失败。
插件项目案例
更多插件链接,敬请关注。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129709.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...