1.UE4-Slate源码学习(一)slate初探
2.UE4游戏客户端开发进阶学习指南
3.UE相关杂项笔记
4.UE4-Slate源码学习(六)slate渲染Part2-Paint控件绘制
UE4-Slate源码学习(一)slate初探
什么是Slate,它与UMG有何不同?
把这个问题交给AI吧。/手动狗头
Slate的创建是通过FGenericApplicationMessageHandler完成的。
FSlateApplication实现了此接口,并定义了处理硬件输入和输出的接口,用于与用户交互。爆枪源码在实现中,大部分函数都是虚函数,由FSlateApplication负责重写。这样,在不同的平台上,可以通过此接口调用到Slate中的事件触发。
UE4游戏客户端开发进阶学习指南
UE4游戏客户端开发的进阶学习指南已经更新,适合有一定基础的读者。本文将引导你深入学习,提供精心筛选的学习资源,分为必修和选修两部分。必修部分包括官方文档的编程与脚本编写、UProperty关键字全说明、GamePlay架构系列和骨骼网格动画等,这些都是开发的基础和核心内容。选修部分涵盖了蓝图开发、C++编程、Gameplay Ability System (GAS)、动画、看懂以太坊源码UI、AI、网络架构以及编辑器扩展等进阶内容,适合根据个人兴趣和项目需求进行选择。
首先,理解UE4的整体架构是关键,官方的引擎架构图能帮助你建立框架认知。接下来,深入学习编程和蓝图开发,理解UObject类型系统,将有助于你构建游戏玩法。GamePlay模块教你如何运用GAS实现各种功能,如游戏阶段切换。动画部分,从官方文档开始,ALS高级运动系统是核心,选修内容涉及过场动画和底层源码解析。UI开发中,UMG控件、Slate和动态创建动画是基础,根据需求选择更深入的内容。
AI部分,从行为树和感知模块入手,选修内容包括行为树源码和寻路算法。dubbo源码如何看懂网络部分,官方文档和网络同步原理是必修,ReplicationGraph插件对于大世界场景尤为重要。编辑器扩展和渲染视觉效果则适合选修学习,如Lyra工程和GameFeature框架提供了UE5新特性的学习机会。
记住,每个模块的资料都是为了帮助你提升UE4客户端开发的技能,根据实际情况选择适合的路径,持续提升你的开发能力。作者的个人博客资源供你参考和深入学习。
UE相关杂项笔记
UE引擎的相关知识整理如下:
1. Pak包解析:在UE4中,通过在CMD控制台输入"D:"Epic Games"\UE_5.1\Engine\Binaries\Win\UnrealPak.exe" 包路径 -list"(注意空格需加双引号)来查看Pak包内包含的文件。解包工具路径位于UE引擎安装路径的相应文件夹内。
2. 清理缓存与修改路径: UE5的默认缓存位于"C:\Users\"用户名"\AppData\Local\UnrealEngine\Common\DerivedDataCache"。要修改缓存路径,需定位到UE_5.1\Engine\Config\BaseEngine.ini,替换相关路径。
3. 番茄助手功能:Visual Assist X中,快捷键如Alt+O用于切换.h和.cpp,Shift+Alt+O查找定义,Shift+Alt+G查找继承链等。更多快捷键请参阅相关博客。
4. VS自动对齐:在VS中,使用Ctrl+K+D或Ctrl+A+Ctrl+K+Ctrl+F可实现代码的镇店指标源码全选对齐或部分代码对齐。
5. 蓝图间通信:通过执行控制台命令函数实现不同蓝图间的通信,例如在关卡蓝图中使用特定事件名。
6. 打包后的模拟触摸:Window打包成exe后,添加-faketouches参数可模拟移动端触感。
7. 基础UEC++知识:包括设置颜色和透明度、正确引入Windows头文件等。
8. UMG问题:ScrollBox在出现滚动条后,鼠标右键点击事件可能失效,需取消勾选"允许点击右键拖动滚动"选项。
9. 编辑器语言设置:确保勾选"使用本地化数字输入"和"使用本地化属性命名"来解决中文显示问题。
. 物体高速移动问题:通过修改抗锯齿设置为TAA,可以解决运动残影问题。
. ScrollBox子项Button的交互:在Touch Method中设置为Precise Tap,避免Button在滑动中被选中。
. 项目报错处理:通过VS输出窗口查找错误资源路径,或在引擎源代码中设置断点进行调试。
. 编辑器操作问题:在编辑器设置中调整"播放-游戏获取鼠标设置"以改善鼠标交互。
. 引擎工具笔记:涵盖引擎工具的使用和维护。
. 后期材质问题:解决postprocess材质闪烁问题,可通过调整抗锯齿设置来优化。
. 报错解决:确保静态函数库中不包含WorldContext输入,重启项目即可避免"Ensure condition failed"报错。
. 绘制多边形:参考割耳算法和相关视频教程,如细思实验室的说明书源码分享,创建绚丽多变的项目效果。
. HTTP响应问题:对于"invalid HTTP response code received"警告,需要排查虚幻引擎与网络请求的兼容性问题。
UE4-Slate源码学习(六)slate渲染Part2-Paint控件绘制
上一篇文章介绍了绘制一个SWindow的初期步骤,即计算整个UI树的控件大小,为绘制做准备。文章随后深入探讨了绘制流程的第二步,即执行FSlateApplication::PrivateDrawWindows()后,开始调用SWidget::Paint()函数,每个控件随后实现其虚函数OnPaint()。
在这一过程中,绘制参数被封装在FPaintArgs中,作为Paint和OnPaint过程中的关键引用参数。FSlateRHIRenderer与FSlateDrawBuffer是继承自FSlateRenderer的类,作为FSlateApplicationBase的全局变量,在构造时创建。在绘制过程中,通过GetDrawBuffer()函数可获取到FSlateDrawBuffer对象。
FSlateDrawBuffer实现了Slate的绘制缓冲区,内部封装了FSlateWindowElementList数组,用于存储多个SWindow下的绘制元素列表。每个SWindow通过AddWindowElementList()返回一个元素列表。
FSlateWindowElementList负载了SWindow内的所有图元信息,内部封装了FSlateDrawElement的数组,包含Cached和Uncached元素,以及SWindow的指针和用于渲染的批处理数据FSlateBatchData。
FSlateDrawElement是构建Slate渲染界面的基本块,封装了UI树节点控件需要渲染的相关信息,如渲染变换、位置、大小、层级ID、绘制效果等,以及后续渲染阶段需要的相关数据。
在Paint流程中,处理当前传入的SWindow和ChildWindows,首先判断窗口是否可见和是否最小化,然后从参数封装的OutDrawBuffer中获取WindowElementList。调用SWindow的PaintWindow()函数开始绘制窗口,并最终返回所有子控件计算完的最大层级。接着,子窗口递归绘制。
PaintWindow()函数在绘制窗口时,首先调用SetHittestArea()设置点击区域,HittestGrid会判断窗口大小是否改变,若不变则仅更新窗口在屏幕中的位置。构造FPaintArgs参数后,将其封装到FSlateInvalidationContext中。
FSlateInvalidationRoot类的PaintInvalidationRoot()函数可以作为控件树的根节点或叶子节点(SInvalidationPanel),构建快速路径避免每次绘制都计算大小和Paint函数,有利于优化。本篇文章主要分析正常慢速路径调用流程,优化相关将另文分析。
PaintSlowPath()函数从SWindow开始调用Paint()函数,并定义LayerId从0开始作为参数,进行实际的绘制相关计算。
Paint()函数首先处理裁剪、透明度混合、坐标转换等代码。若SWidget包含NeedsTick掩码,则调用Tick函数,我们在日常开发中通过蓝图或lua使用Tick函数时即调用到这里,通过SObjectWidget::Tick调用到UUserWidget::NativeTick供实现Tick。构造FSlateWidgetPersistentState PersistentState作为SWidget的变量,表示Paint时的状态。
PersistentState.CachedElementHandle将当前SWidget存储到FSlateWindowElementList中的WidgetDrawStack数组中。
更新FPaintArgs中的父节点参数和继承可点击测试参数,判断点击测试状态,然后将当前SWidget添加到点击测试中。调用虚函数OnPaint,由控件自己实现。
OnPaint()函数参数包括绘制参数引用、几何体、裁剪矩形、缓冲元素列表、层级、控件风格、父节点状态等。最后处理重绘标签、延迟绘制相关内容、UpdateWidgetProxy()根据缓存句柄更新快速路径中需要处理标记设置为Volatile不稳定状态的SWidget。
虚函数OnPaint()由子类自己实现,本文列举了SImage、SButton、SCompoundWidget和SConstraintCanvas的OnPaint()示例代码学习。
在SImage中,简单判断Brush是否存在以及BrushDrawType的类型,然后调用FSlateDrawElement::MakeBox将控件添加到缓冲区元素列表中。
SButton继承自SCompoundWidget,GetBorder()根据当前按钮状态返回ui中设置的Enabled、Press、Hover、Disabled等状态的Brush。
SCompoundWidget作为合成节点,有且只能有一个子节点,且在Paint时强制将子节点的LayerId+1,同时SCompoundWidget可以单独设置混合颜色和透明度,影响子节点。
SConstraintCanvas作为SWidget的基类对应UMG中常用的UCanvasPanel,通过ArrangeLayeredChildren()对孩子进行层级排序,并根据孩子的层级是否相同存储bool值在ChildLayers中。遍历所有孩子,判断是否开启新层级,递归调用Paint函数,最后返回最大层级。
SConstraintCanvas::ArrangeLayeredChildren函数中,获取设置bExplicitChildZOrder,表示可以将同层一次渲染,有利于提高渲染器批处理。对所有孩子排序,排序规则为FSortSlotsByZOrder。遍历所有孩子,判断可见性掩码、计算偏移、锚点、位置、拉伸缩放等,封装成FArrangedWidget存储到ArrangedChildren中,用于OnPaint时有序遍历。判断每个孩子ZOrder是否相同,相同则bNewLayer为false,大于LastZOrder则将bNewLayer设置为true,最终存储到ArrangedChildLayers中,用于OnPaint函数判断是否将layerId+1。
FSlateDrawElement::MakeBox()函数在OnPaint之后调用,将绘制控件的相关信息通过创建FSlateDrawElement绘制元素对象,添加到SWindow管理的FSlateWindowElementList元素列表中。创建Payload用于存储贴图等相关信息,根据控件Paint过程中的参数调用Element.Init初始化绘制元素,得到为该控件绘制创建的FSlateDrawElement对象。
总结整个Slate绘制流程的第二步,我们没有分析快速处理和优化细节,而是按照正常绘制流程分析代码。通过从PaintWindow开始遍历整个控件树,处理每个空间节点的Paint、OnPaint函数,最终目的是给每个控件创建一个FSlateDrawElement对象,存储渲染线程绘制所需的相关信息,并添加到FSlateWindowElementList中。理解了整个调用流程,整个过程较为清晰,本文基于UE4版本4..2。