目录
引言
一、创建一个C++插件TextureReader插件
二、Build.cs文件
三、ModuleRules
四、TextureReader插件的构造
4.1ReadOnlyTargetRules的作用
4.2TextureReaderd的构造调用
4.3设置当前类的预编译头文件的使用模式
4.4PublicIncludePaths.AddRange与PrivateIncludePaths.AddRange
五、加载PrivateIncludePathModuleNames
5.1Core
5.2UMG
引言
在UE5中我们可以点开插件功能,我们可以看到有很多的插件供我们选择和下载,其中除了UE官方给我们提供了非常丰富的插件以外,来自世界各地的UE开发者也上传了很多自己实现的插件,同样,我们也可以实现自己想要的插件。以下,博主将从自己在公司实习过程中所掌握的开发技巧作以分享,从0自己实现一个加载特定路径下不同类型图片的插件。
一、创建一个C++插件TextureReader插件
点击添加插件,我们创建一个蓝图库类型的插件。可以自己对齐进行命名操作。
创建完毕后,在VS中我们可以清晰的看到Plugins目录下保存着我们刚刚创建的插件文件夹。
二、Build.cs文件
点击C#开头的Build.cs文件夹我们可以看到以下结构:
在Unreal Engine(UE)项目中,Build.cs
文件是一个非常重要的配置文件,用于定义项目的构建设置和依赖关系。这个文件是Unreal Engine 4(UE4)及更高版本(如UE5)中使用的C#脚本,属于Unreal Build Tool(UBT)的一部分。UBT是Unreal Engine的专用构建系统,用于编译和管理项目的构建过程。
Build.cs
文件的主要作用包括:
- 定义项目依赖:在
Build.cs
中,你可以指定项目所依赖的其他模块。这确保了当构建你的项目时,所有必需的模块都会被正确编译和链接。 - 配置构建平台:你可以为不同的平台(如Windows、Mac、Linux、Android、iOS等)设置特定的构建选项。这包括定义条件编译符号、平台特定的库依赖等。
- 设置编译选项:你可以在这里定义编译器标志、优化级别、调试信息等编译选项。
- 管理项目模块:
Build.cs
文件允许你定义和配置项目中的模块(Modules)。模块是UE项目的基本构建块,可以包含代码、资源、插件等。 - 插件和第三方库:如果你的项目使用了第三方库或UE插件,你可以在
Build.cs
中配置这些依赖,确保它们被正确集成到构建过程中。 - 自定义构建步骤:虽然不常见,但在某些高级用例中,你可以定义自定义的构建步骤或脚本,以在标准构建过程之前或之后执行特定的任务。
而在Build.cs文件中我们可以看到我们刚刚所命名的TextureReader被定义为一个类,并且继承自一个名为ModuleRules的父类。
三、ModuleRules
在UE中,ModuleRules
是一个非常重要的类,它用于定义和配置模块的编译规则。这些规则包括模块的类型、依赖关系、包含路径、库路径等,它们共同决定了模块如何被构建和集成到UE项目中。而ModuleRules
的详细作用体现在以下几个方面:
一、定义模块类型
ModuleRules
类中的Type
属性用于指定模块的类型。在UE中,模块可以是标准的C++模块(CPlusPlus
),也可以是外部的第三方模块(External
)。这个属性对于UE构建系统来说至关重要,因为它决定了模块如何被构建和管理。
二、管理依赖关系
ModuleRules
类提供了多个属性来管理模块的依赖关系,包括:
PublicDependencyModuleNames
:公共依赖模块名称列表。这些模块对于当前模块的公共代码是可见的,并且会在编译时被链接到当前模块中。PrivateDependencyModuleNames
:私有依赖模块名称列表。这些模块仅对当前模块的私有代码可见,并且会在编译时被链接到当前模块中,但不会被其他模块看到。
通过管理这些依赖关系,ModuleRules
确保了模块之间的正确链接和隔离,从而提高了代码的可维护性和可扩展性。
三、指定包含路径和库路径
ModuleRules
类还提供了多个属性来指定模块的包含路径和库路径,包括:
PublicIncludePathModuleNames
和PrivateIncludePathModuleNames
:这些属性用于指定包含头文件的模块名称列表,它们分别对应公共和私有包含路径。PublicSystemIncludePaths
和PrivateSystemIncludePaths
:这些属性用于指定系统/库包含路径列表,它们通常用于外部(第三方)模块。PublicRuntimeLibraryPaths
和PrivateRuntimeLibraryPaths
:这些属性用于指定运行时库的搜索路径列表。
通过指定这些路径,ModuleRules
确保了编译器能够正确地找到和包含所需的头文件和库文件。
而我们实现插件的第一步也就是要对这几个继承自父类ModuleRules的属性进行编辑。
四、配置附加库和延迟加载
ModuleRules
类还提供了属性来配置附加库和延迟加载的DLL文件。例如:
PublicAdditionalLibraries
:附加库的列表(.lib文件的名称,包括扩展名),通常用于外部(第三方)模块。PublicDelayLoadDLLs
:用于指定需要在程序运行时延迟加载的DLL文件列表。
这些配置有助于优化程序的启动速度和内存使用,同时提高了程序的灵活性和可扩展性。
四、TextureReader插件的构造
4.1ReadOnlyTargetRules的作用
在Unreal Engine(UE)中,ReadOnlyTargetRules
是一个结构体(struct),它封装了与目标平台相关的只读编译规则。这些规则定义了如何针对不同的目标(如编辑器、游戏客户端、服务器等)以及不同的平台(如Windows、Mac、Linux、iOS、Android等)进行编译。ReadOnlyTargetRules
类型的参数通常用于配置和初始化那些需要根据目标平台差异而调整其行为或特性的类、函数或模块。
ReadOnlyTargetRules
的主要用途:
-
平台特定设置:提供平台特定的编译选项,例如是否启用某些特性、是否包含特定的头文件或库等。
-
编辑器与游戏区分:允许代码在编辑器模式下和游戏模式下有不同的行为。例如,某些调试功能或编辑器专用的工具可能只在编辑器模式下可用。
-
性能优化:根据目标平台的性能特性,调整代码以优化性能。例如,在移动设备上可能需要减少内存使用或降低图形质量。
-
兼容性处理:处理不同平台之间的兼容性问题,确保代码能够在所有目标平台上正确运行。
ReadOnlyTargetRules
参数的使用场景:
-
类构造函数:在类的构造函数中使用
ReadOnlyTargetRules
参数,以便根据目标平台初始化类的成员变量或配置类的行为。 -
函数参数:将
ReadOnlyTargetRules
作为函数参数传递,以便函数能够根据目标平台执行不同的操作。 -
模块配置:在模块的构建脚本(如UE4中的
Build.cs
或UE5中的MyModule.Build.cs
)中使用ReadOnlyTargetRules
来配置模块的编译选项。
4.2TextureReaderd的构造调用
TextureReaderd类的构造函数接收一个ReadOnlyTargetRules
类型的参数Target
,并将其传递给基类(base
)的构造函数。下面是对这段代码的详细解读:
类的定义与构造函数
- 类名:
TextureReader
- 构造函数:
public TextureReader(ReadOnlyTargetRules Target) : base(Target)
构造函数参数
- 参数类型:
ReadOnlyTargetRules
- 参数名:
Target
(注意,这里的Target
是参数名,并非关键字,因此可以使用小写) - 参数用途:此参数通常包含了目标平台的编译规则,例如是否针对编辑器、游戏,或是特定硬件平台(如PC、移动设备等)的编译设置。
基类构造函数调用
base(Target)
:这部分代码表示调用TextureReader
基类的构造函数,并将Target
参数传递给它。这是C++中初始化基类部分的标准做法。
4.3设置当前类的预编译头文件的使用模式
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
这行代码用于设置预编译头文件(Precompiled Headers,简称PCHs)的使用模式。UE中的PCHs是一种优化技术,它允许开发者将常用的头文件编译成单个预编译文件,从而加速编译过程并减少编译时间。
让我们详细解释一下这行代码的含义:
-
PCHUsage:这是一个属性或设置项,用于指定当前模块如何使用PCHs。
-
ModuleRules.PCHUsageMode:
ModuleRules
是一个类,它定义了模块的编译规则。PCHUsageMode
是ModuleRules
类中的一个枚举类型,用于指定PCHs的使用模式。 -
UseExplicitOrSharedPCHs:这是
PCHUsageMode
枚举中的一个值,它表示模块将使用显式定义的PCHs或共享PCHs。-
显式PCHs:开发者需要在模块的Build.cs文件中明确指定哪些头文件应该被包含在PCH中。这通常是通过
PublicPCHHeader
或PrivatePCHHeader
属性来实现的。 -
共享PCHs:UE项目可以配置一个或多个共享PCHs,这些PCHs包含了项目中多个模块共同需要的头文件。当模块设置为使用共享PCHs时,它会自动包含这些共享PCHs中的内容。
-
将PCHUsage
设置为UseExplicitOrSharedPCHs
意味着开发者可以选择为当前模块指定显式的PCH,或者如果项目配置了共享PCHs,则模块将使用这些共享PCHs。这提供了灵活性,允许开发者根据项目需求和模块特性来决定最佳的PCH使用策略。
4.4PublicIncludePaths.AddRange与PrivateIncludePaths.AddRange
PublicIncludePaths.AddRange()
方法的作用主要是向项目的公共包含路径集合中添加一组路径。以下是对其作用的详细解释:
作用
- 添加公共路径:
AddRange
是一个集合方法,用于将一个集合(如数组、列表等)中的所有元素添加到另一个集合中。在UE的项目配置中,PublicIncludePaths
是一个包含公共头文件路径的集合。通过调用PublicIncludePaths.AddRange
方法,你可以将一组新的路径添加到这个集合中。
- 公共性:
PublicIncludePaths
中的路径不仅对当前项目可见,还可能对依赖此项目的其他项目或模块可见。这意味着,通过添加路径到PublicIncludePaths
,你确保这些路径中的头文件在编译过程中可以被当前项目及其依赖项访问。
- 头文件包含:
- 包含路径(Include Paths)是编译器在查找头文件时应该搜索的目录列表。在C++等编程语言中,头文件包含函数声明、宏定义等,这些文件在编译过程中被包含(include)到源文件中。
PublicIncludePaths
中的路径允许编译器在编译当前项目及其依赖项时找到并包含这些公共头文件。
- 包含路径(Include Paths)是编译器在查找头文件时应该搜索的目录列表。在C++等编程语言中,头文件包含函数声明、宏定义等,这些文件在编译过程中被包含(include)到源文件中。
应用场景
- 多项目共享头文件:
- 当你有多个项目需要共享相同的头文件时,可以将这些头文件的路径添加到
PublicIncludePaths
中。这样,所有依赖这些头文件的项目都可以访问它们,而无需在每个项目中单独配置路径。
- 当你有多个项目需要共享相同的头文件时,可以将这些头文件的路径添加到
- 使用第三方库:
- 当你使用第三方库时,通常需要将库的头文件路径添加到项目的包含路径中。如果这些头文件需要被多个项目或模块访问,那么将它们添加到
PublicIncludePaths
是一个合适的选择。
- 当你使用第三方库时,通常需要将库的头文件路径添加到项目的包含路径中。如果这些头文件需要被多个项目或模块访问,那么将它们添加到
- 模块间依赖:
- 在UE中,模块之间可能存在依赖关系。如果一个模块需要访问另一个模块的头文件,那么可以将这些头文件的路径添加到
PublicIncludePaths
中,以确保在编译过程中可以正确找到并包含它们。
- 在UE中,模块之间可能存在依赖关系。如果一个模块需要访问另一个模块的头文件,那么可以将这些头文件的路径添加到
配置方式
- 在UE的C++项目中,
PublicIncludePaths.AddRange
方法通常在项目的.Build.cs
文件中被调用。你需要在这个文件中找到或创建PublicIncludePaths
集合,并调用AddRange
方法将新的路径添加到集合中。
PrivateIncludePaths.AddRange()
方法的作用主要是向项目的私有包含路径集合中添加一组路径。以下是对其作用的详细解释:
- 添加私有路径:
AddRange
是一个集合方法,用于将一个集合(如数组、列表等)中的所有元素添加到另一个集合中。在UE的项目配置中,PrivateIncludePaths
是一个包含私有头文件路径的集合。通过调用PrivateIncludePaths.AddRange
方法,你可以将一组新的路径添加到这个集合中。
- 私有性:
- 与
PublicIncludePaths
不同,PrivateIncludePaths
中的路径仅对当前项目可见,不会影响到依赖此项目的其他项目。这意味着,通过添加路径到PrivateIncludePaths
,你确保这些路径仅在当前项目的编译过程中被使用。
- 与
- 头文件包含:
- 包含路径(Include Paths)是编译器在查找头文件时应该搜索的目录列表。在C++等编程语言中,头文件包含函数声明、宏定义等,这些文件在编译过程中被包含(include)到源文件中。
PrivateIncludePaths
中的路径允许编译器在编译当前项目时找到并包含这些私有头文件。
- 包含路径(Include Paths)是编译器在查找头文件时应该搜索的目录列表。在C++等编程语言中,头文件包含函数声明、宏定义等,这些文件在编译过程中被包含(include)到源文件中。
- 应用场景:
- 在UE项目中,你可能有一些头文件不希望被其他项目或模块访问,这时可以将这些头文件的路径添加到
PrivateIncludePaths
中。 - 当你使用第三方库或自定义的模块,并且这些库或模块的头文件需要被包含到你的项目中,但又不希望它们被外部访问时,也可以将这些路径添加到
PrivateIncludePaths
中。
- 在UE项目中,你可能有一些头文件不希望被其他项目或模块访问,这时可以将这些头文件的路径添加到
- 配置方式:
- 在UE的C++项目中,
PrivateIncludePaths.AddRange
方法通常在项目的.Build.cs
文件中被调用。你需要在这个文件中找到或创建PrivateIncludePaths
集合,并调用AddRange
方法将新的路径添加到集合中。
- 在UE的C++项目中,
五、加载PrivateIncludePathModuleNames
私有依赖模块仅对当前模块可见,其他模块无法直接访问这些私有依赖。这有助于减少模块间的耦合度,提高代码的可维护性和可扩展性。所以我们将此次TextureReader插件所需要用到的模块加载到PrivateIncludePathModuleNames中。
PrivateDependencyModuleNames.AddRange(new string[]{"CoreUObject","Engine","Slate","SlateCore","ImageWrapper",//图像类的总的模块类"Core","UMG"// ... add private dependencies that you statically link with here ... });
5.1Core
Core模块在Unreal Engine中扮演着至关重要的角色,它提供了游戏开发所需的基础数据类型、数据结构、跨平台支持、内存管理等功能。
核心功能与重要性
- 基础数据类型与结构:Core模块提供了游戏开发中所需的基础数据类型和数据结构,这些是构建更复杂游戏逻辑和系统的基石。
- 跨平台支持:包含了针对不同平台的代码和资源,如Android、iOS、Windows等,使得游戏能够轻松地在多个平台上运行。
- 内存管理与优化:高效的内存管理机制有助于游戏开发者优化游戏的性能,减少内存泄漏和浪费,从而提升游戏的运行效率。
- 基础框架与功能:提供了引擎的基本框架和功能,如日志记录、配置管理、数学运算等,这些都是游戏开发中不可或缺的部分。
5.2UMG
UMG(Unreal Motion Graphics UI Designer)是一个重要的可视化UI(用户界面)创作工具。UMG的作用主要体现在以下几个方面:
一、创建和编辑UI元素
UMG允许开发者创建各种UI元素,如游戏中的HUD(平视显示器)、菜单、按钮、复选框、滑块、进度条等。这些元素是构成游戏用户界面的基础,通过UMG,开发者可以轻松地设计和布局这些元素,以满足游戏的需求。
二、编辑界面布局
UMG提供了强大的布局编辑功能,开发者可以在可视化的界面中拖放控件,调整它们的位置、大小和属性。此外,UMG还支持多种布局面板,如Canvas Panel(画布面板)、Grid Panel(网格面板)、Horizontal Box(水平框)和Vertical Box(纵向框)等,这些面板可以帮助开发者实现复杂的界面布局。
三、编辑界面动画
除了静态的UI元素外,UMG还支持创建和编辑界面动画。通过UMG,开发者可以为UI元素添加动画效果,如淡入淡出、滑动、缩放等,以提升用户界面的交互性和视觉吸引力。
四、处理UI交互
UMG与虚幻引擎的蓝图系统紧密集成,允许开发者在蓝图中处理UI交互。通过蓝图,开发者可以定义UI元素的响应事件,如按钮点击、滑块拖动等,并编写相应的逻辑来处理这些事件。这使得开发者能够轻松地实现用户界面的交互功能。
这也是我们创建的蓝图类的插件所必不可少的一个模块,所以必须要加载进来
五、优化性能和内存管理
UMG还提供了多种优化性能和内存管理的功能。例如,开发者可以使用无效框(Invalidation Box)来缓存UI绘制的中间数据,减少绘制的CPU消耗。此外,通过合理结构提升渲染性能,如减少UI层级、合并图集等,可以进一步优化游戏的性能表现。
六、与Slate的关系
UMG是基于Slate构建的界面编辑系统。Slate是虚幻引擎的底层UI框架,负责执行控件的逻辑(包括渲染和事件)。UMG则是对Slate的封装,提供了更友好、更直观的界面编辑工具,使得开发者能够更方便地创建和编辑用户界面。
博主作为第一次接触UE开发的新手,搞懂以上内容也花费了大量的实践和精力,而熟悉C++的特性语法以及常见的开发技巧也只是学习UE开发的万里长征第一步,唯有不断学习不断提升才能真正的掌握其精髓,成为一个真正的UE开发工程师