1 从源码编译UE4

Unreal Engine是源码开放软件而不是开源软件。在获取引擎源码之前,需要加入Epic的Github组织,然后才能下载。从下载到跑起来,要经历下载源码、下第三方库、生成工程sln文件、编译引擎等步骤,可以看看这些资料:

协议里提到,分享源码有一个30行的限制。这个尽量遵守。

我的小笔记本和长城宽带做这些事情都是比较慢的。在编译引擎代码的时候,遇到了 fatal error C1060: 编译器的堆空间不足fatal error C1002: 在第 2 遍中编译器的堆空间不足error C3859: 超过了 PCH 的虚拟内存范围 等报错。原因和解决方法可以参考以下博文:

如果只改factor的值,我还是编译不成。最终用了跟最后一篇完全一样的方法,修改到100、设置分页大小 64M-2927M。

2 Rider for UE

之前没用VS写过UE的C++(只用了蓝图),但看过一些Rider跟VS相比的文章,据说Rider全局搜索和跳转的速度快很多。因此我就直接下了个Rider来用。

JetBrains 的 IDE,我至今应该用过 WebStorm、IntelliJ IDEA、PyCharm 了,现在又在用 Rider。因此就打算把一些使用上的小习惯整理一下,也把在VS里用得顺手的部分迁移过来,延续下去。这里以 Rider + Unreal 为例,记录一些 IDEA 风格的 IDE 常用的快捷键,以及调试方法。(持续更新)

白嫖学生免费的方法

可以看看这两篇文章:

我的edu邮箱不能直接申请,也是用了学信网。但也要填一个edu邮箱。过几天后,edu邮箱会收到邮件告知通过,并有一个链接可以把学生资历绑定到账号上。

不知为何,我没能将我的学生免费绑定在已有的账号上(绑定已有账号后,显示成功,但库里没有免费license),并且经过这一步后,收到的邮件也点不进去了。一番尝试后,我发现再用学生邮箱重新注册一个新号,注册完后就可以直接在库里找到免费的license,并且用户名直接给我实名上网了。大概是必须用之前填写的edu邮箱账号享受学生优惠吧。

之后要把UE跟Rider关联起来,看这篇文章:【UE4】Rider For Unreal体验报告

Rider 快捷键

打开File->Settings->Keymap,就可以设置快捷键了。我使用IntelliJ Keymap,不再使用VS

(个人习惯)首先,修改在VS里用得很顺的快捷键:

  • Split Line 改为 Shift + Enter,Start New Line 改为 Ctrl + Enter(互换)
  • Switch Header/Source 添加快捷键 Alt + O

查找快捷键:

  • Ctrl + Shift + F 全局查找
  • Ctrl + F 文件内查找

用到方向键的快捷键:

  • Alt + 左右 切换打开的文件
  • Alt + 上下 文件内移动到相邻方法
  • Ctrl + 左右 移动光标到相邻单词
  • Ctrl + 上下 滚屏
  • (个人习惯)上面是原始的快捷键,我把Alt + 上下Ctrl + 上下交换了一下。这样,按 Ctrl 就是在文件内跳转光标位置,按 Alt 就是在切屏(正好我的 Alt + O 也是在切文件),我个人觉得更好记一些
  • Shift + 方向键 选中

在Main Menu->Navigate里可以看一些导航常用的快捷键

  • 通常用 Ctrl + Click 速览定义/使用。这是可以使用鼠标4/5键,在光标位置之间移动(用于上一个操作的返回)。大拇指往下抠是向前,往上抠是向后。(公司电脑没有侧键,点击左上角两个方向图标)
  • Ctrl + N 查找类
  • Ctrl + Shift + Backspace 到上个编辑点

3 调试

Unreal + VS 的调试方法,参考这个视频:如何调试UE4引擎源码

Rider中的调试方法,参考这篇文章:Intellij IDEA中使用好Debug调试

这里整理一下UE + Rider的调试方法。事先,要从源码编译过引擎后,在引擎里新建一个项目,这一步就不多说了,只提有了项目之后的调试。

首先在Rider编译项目的Development Editor版本,然后在UE中把项目打一个debug包(只有用源码版引擎的时候才能打debug包)。此时,项目/Binaries/Win64/下就有一个可执行的Debug.exe文件了。

然后,在Rider切换到项目的Debug版本,点Debug,就可以对引擎源码进行调试了。游戏会自动打开。

一个小技巧:Rider点Debug肯定就是打开最后打包好的Debug版本的游戏了(好像是在Binaries目录下面),但在Editor打包可以多搞几个文件夹、把好几个版本的包都保存下来。虽然不能调试引擎源码,但能看一下游戏里的表现,WidgetReflector之类的各种命令行也能用。对于做一些对比工作比较方便。

基本

这里详细说一下Rider+Unreal调试的过程。

当游戏开始后点击Rider里的暂停,这时可以看到游戏的各个线程

点开一个线程可以看到函数调用栈,比如这里点开主线程,可以看到在做Slate相关的一些事情。游戏时时刻刻在做各种各样的事情,多暂停几次会发现函数调用栈都很不相同

可以对照上面的VS视频,在VS里也是一样,跑Debug模式,然后按全部中断,可以选线程然后看函数调用栈

断点

回到Rider,接下来展示一下打断点调试的过程。首先,可以在上面暂停游戏后,在代码中打断点,然后继续运行。

也可以事先打断点,比如我想看引擎在初始化阶段都做了什么(相关的过程可以看另一篇文章),可以在PreInit里随便打个断点,点击Debug后程序就会跑到这里停下,下方可以看相应的函数调用栈。

插播一条,如图,debug模式下也可以看到已执行函数的参数值,函数的返回值,等。写在这一行的后面。

然后,比较常用的就是框出的那几个按钮。其中我基本上只用中间的3个。

绿色“继续”按钮就是运行到下一个断点执行之前。蓝色的三个,第一个是跳到当前方法执行完的地方,第二个是一行行地执行,如果遇到方法就进入方法内部。

比如从这里,我想进入PreInitPreStartupScreen()看看,就点蓝色的第二个。在方法其中,可以打一些断点,那么我就点绿色的继续按钮,程序会执行到下一个断点处。通过类似的方法,在FPreLoadScreenManager::Get()->Initialize(SlateRendererSharedRef.Get());打了个断点后发现,这一步执行之后,游戏的窗口就被创建出来了。

一步步到PreInitPostStartupScreen中的ProcessNewlyLoadedUObjects();执行完后,游戏窗口变黑了。

但我不是很关心这个窗口具体发生了什么,这时我可以点击蓝色的第三个按钮Step Out,跳转到PreInitPostStartupScreen执行结束的地方。

然后,如果发现之前有些断点没啥用,就点击倒数第二个叠起来的断点按钮,其中可以看到打过的所有断点,也可以在下方的代码预览框里把这个断点删掉。

最终,在Tick()方法中的FSlateApplication::Get().Tick(ESlateTickType::TimeAndWidgets);执行完后,窗口就画出了游戏画面了。然后就可以进入这个方法,看看到底是如何把游戏世界画出来的。

这就是我用这几个按钮的方法。

条件断点

在普通断点处点右键,condition里写语句就可以了。拿Slate举例,比如从WidgetReflector里查到一个控件的地址,可以打 this==0x1f19e44a190 让程序停到该控件的Paint()里;或者是 ThisIndex>=3 这种判断某一帧有更多控件加入了循环,类似的语句都可以。

数据断点

我也不知道怎么在Rider里打数据断点。在官方文档有个图片,看的应该是先把数据加入watch列表,然后右键可以设置数据断点,但是我右键没有这个选项。

文档还提了一句不支持2020.2的结构体的字段和属性,可能是这个原因吧。总之不是很清楚怎么在rider用数据断点。