之前一直被事情困着没有时间写博客,最近准备把最近一段时间的学习总结写成博客,这篇博客记录分享如何使用UE4来开发自定义插件,此处使用环境为UE4.25+vs2017,作为一个系列将以每篇一个插件作为示例介绍插件从编写到打包整个过程。
该篇制作mysql的插件,此处所用为mysql8.0的库文件,如果有需要也可以到我的资源中下载,我之前已经将插件打包上传了,同时我也新建了一个qq群,如果有想共同学习的同学也可以加群一起学习讨论,1108357242.
开发步骤:
1.新建基于c++的UE4工程
2.在设置->插件中新建空白插件,注意不要跟工程名同名,否则可能出现新建失败的情况。
3.新建成功之后回到UE4界面,在内容浏览器下面找到刚刚新建插件的文件夹,在该文件夹下面创建两个cpp文件,一个是基于object的插件基类,还一个是基于蓝图函数库的功能类,此处需要注意的是新建类的时候,目标模块要选择刚刚新建的插件,不要是默认的工程部分,还有就是选择public,下面展示一个基于object的部分,当点击创建类之后可能会出现自动编译消息失败,不用管,点否就行了,此时我们关闭整个工程,然后用vs打开工程,接下来编写插件具体内容。
4.到以上三步基本上是完成了基础UE4插件配置,然后我们需要配置mysql库,关于配置库,我们需要h文件和lib文件,具体步骤如下:
1)首先我们需要把库导入到工程里面来,接下来结构化库,在工程目录Plugin\MySQLPlugin\Source目录下面新建一个ThirdParty文件夹,在该目录下新建文件夹Connectlibs和一个c#的cs文件,然后先不编写具体c#代码,在Connectlibs文件夹中新建include和lib,然后把对应h文件和lib文件放入其中,接下来编写加载该库的c#代码,cs文件中代码如下,如下代码很简单,就只有几句
using System.IO;
using UnrealBuildTool;
public class ConnectorLibs:ModuleRules
{
public ConnectorLibs(ReadOnlyTargetRules Target):base(Target)
{
Type = ModuleType.External;//
PublicIncludePaths.Add(Path.Combine(ModuleDirectory,"ConnectorLibs","include"));
if(Target.Platform == UnrealTargetPlatform.Win64)
{
PublicLibraryPaths.Add(Path.Combine(ModuleDirectory,"ConnectorLibs","lib"));
PublicAdditionalLibraries.Add("mysqlclient.lib");
//PublicAdditionalLibraries.Add("mysqlclient.lib");
}
}
}
2).将上述步骤做好之后然后右键点击工程.uproject选择Generate visual studio project files,然后打开vs工程在工程属性中添加h文件和lib文件。
5.当前面步骤完成之后我们可以在工程中使用mysql库了,那么我们开始进行编写插件具体功能,首先我们需要在刚刚创建的基类中创建一个MySQL的对象,初始赋值为nullptr,具体如下
//h文件
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include <mysql.h>
#include "MyConnectObject.generated.h"
/**
*
*/
UCLASS(BlueprintType)
class ZHEBOBICHENGGONG_API UMyConnectObject : public UObject
{
GENERATED_BODY()
private:
UMyConnectObject();
public:
MYSQL* Conn;
};
//c文件
#include "MyConnectObject.h"
UMyConnectObject::UMyConnectObject()
{
Conn = nullptr;
}
6.然后就是具体的连接数据库,关闭连接以及增删改查基本功能实现,至于其余一些功能各位也可以根据自己实际需要来扩展。具体的实际内容由于篇幅原因不多赘述,可以自行下载我的资源或者加群找我要,我在这里主要是说一下在UE4中用c++写蓝图的需要注意的,首先就是关于宏的问题,如下面这个连接数据库的函数声明,由于UE4中的c++是魔改之后的,所以说很多部分还是会和原生c++有不同,此处这种UFUNCTION宏就是为了告诉UE4编译器,这是一个函数,第一个参数BlueprintCallable是说明该函数为蓝图调用,也可以理解为创建蓝图吧,后面Category就是规定在蓝图寻找时候的一个归类,我此处将该函数归为SQL Utilities这个分类中。然后就是函数声明需要是静态函数(此处就类似于使用原生c++制作dll函数一样,作为调用的dll函数需要为static),然后还有就是函数的传参方面需要注意,有一些类型是不能被直接使用到参数上的,但是可以在函数内部使用,例如unsigned char,需要使用uint8(ue4中将unsigned char typedef成uint8了)
//连接数据库
UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
static UMyConnectObject* ConnectToMySQL(FString Host, FString userName, FString Password, FString dbName, int32 Port, FString& Msg);
7.最后说一下关于枚举和结构体的使用方法,在UE4中不能直接使用这种数据结构,
1).自定义结构体,首先不能在class中直接声明,在外面定义,如下将我的mysql插件中定义的一个行数据结构体截取出来演示
/**一行所含数据*/
USTRUCT(BlueprintType)
struct FQueryResultRow
{
GENERATED_BODY()
/**一行的数据*/
UPROPERTY(BlueprintReadWrite, Category = "Result Row Value")
TArray<FString> RowValue;
};
这其中GENERATED_BODY()是必须要加的,这是为了将这个结构体加入编译中,还有USTRUCT这个宏也是必须的,至于变量上面的UPROPERTY宏则是为了能够让蓝图可以调用。
2).自定义枚举,关于自定义枚举一般有两种,我在这个插件中未使用枚举,但是我另外编写的一个插件中使用了,我将代码贴出来,后面UMETA部分是表示在蓝图中该值显示的名字
UENUM(BlueprintType)
enum UAXIS_TYPE_E
{
AXIS1 = 0 UMETA(DisplayName="AXIS1"),
AXIS1_X = 1 UMETA(DisplayName="AXISX"),
AXIS1_Y = 2 UMETA(DisplayName="AXISY"),
AXIS1_Z = 4 UMETA(DisplayName="AXISZ"),
AXIS1_U = 8 UMETA(DisplayName="AXISU"),
AXIS1_V = 16 UMETA(DisplayName="AXISV"),
AXIS1_W = 32 UMETA(DisplayName="AXISW")
};
至此该篇写完了,很混乱,可能是思维还没理清楚,等后续再整理了继续写一下。