基础知识总结
蓝图节点
1.蓝图中的节点是封装好的函数。这些函数功能强大,但由于数目繁多且内部实现不明(注:可能是开发环境问题,转到C++代码这一步永远无法执行),总会出现一些不明所以的bug(比如默认的绕X、Y、Z轴旋转方向不一样)。所以最重要的不是函数功能本身,是函数的输入/输出变量的数据结构。
2.常见的入门节点在前文已经介绍过,日后能看源码了会解析一下我认为做的巧妙的节点。
3.一些能提高效率的操作:通过输入/输出参量进口拉出引脚直接创建变量。灵活使用复制功能避免重复操作。数学计算尽量封装成函数(好像是废话)。
4.一些复杂节点输出的数据结构在官网的技术文档也查不到,加上看不到源码,只能推测其内部特性和存储方式。在学习初期,这些困难只能通过灵活使用博客和chatGPT解决。
第二周展望
1.蓝图的学习仍需继续。现在能够做出的东西根本不能称之为作品,充其量只能算是“HelloWorld”。UI、角色、视角调整,这些与人类交互的东西才是游戏区别于其他艺术形式最本质的东西。
2.必须想办法看到各种函数、对象的C++源码。如果我们不了解手中的工具,那么我只能完成一些很基础的工作。
3.必须持续精进C++水平。蓝图中的对象继承错综复杂,接口多种多样。要想高效率的学习,不仅要正确的读懂C++代码,更要快速高效的阅读C++代码。提高代码的阅读速度,就需要熟练度。
4.阅读是为了更好地编写。必须独立编写更多C++代码,哪怕只是把刚刚看到的代码复述性的重写一遍。
入门第一周项目:会旋转的魔方
需求分析
1.魔方本身是一个正方体,其本体又是由N3个小魔方组成的。对于魔方整体而言,六个面分别拥有六种不同的颜色,而这一个方向上的颜色又是又组成魔方的小方块提供的。
2.魔方的旋转共有3N种,可以由29(N-1)种旋转等价代替(注:这里不考虑正反方向,默认向坐标轴正90度旋转)。出于美观,我们应当实现所有旋转。
3.魔方的小方块是固定在魔方上的,因此在魔方的某一层旋转时,小方块必须同步旋转。
设计思路
1.针对需求1,我们需要一个创造魔方的功能。这个功能在给定N的情况下要能做到创建N3个小方块并把它们放在正确的位置上。而小方块虽然会有很多面被挡住无法在外部看见,我们仍可以把每个小方块的六个面都涂上颜色,这样一整个魔方的所需要的小方块就都是同一对象。小方块的创建我们可以在3dmax和材质界面实现。
2.针对需求2,我们必须清楚魔方旋转的本质是什么。在一个由N3个小方块组成的魔方中,旋转的本质就是选定同属一 层 的小方块,令这些小方块绕给定的 坐标轴 旋转。因此,我们必须用某种方法,选中一次旋转中的所有小方块。
3.针对需求3,我们会注意到,在UE5中,物体绕坐标轴的旋转不会改变物体本身在世界中的相对旋转角,这会导致一种十分生草的结果出现,就像无论身子如何头都很稳定的鸟类,小方块始终保持同一角度移动到目标位置。而且稍加推演我们就会得出一个显然的结论:这样旋转后,魔方上各个面的颜色不会有任何变化。
综上所述,解决需求不可能只靠在第一周介绍的那些基础节点,我们必须引入一些新节点来解决问题。
新节点
1.AddStaticMeshComponent:在Actor对象中,所有的静态模型成员(StaticMeshComponent)都可以通过这个节点来创造。只要循环N3次,就能创造出我们需要的N3个小方块。至于每个小方块的相对位置,建议经过计算后用Transform数据类型接入这个节点。
2.MakeTransform:用这个节点解决上面的Transform数据类型。
3.SetTimerbyEvent:创建一个事件计时器,在计时器归0时触发一个事件,建议搭配CustomEvent使用。勾选looping会自动循环,基本必选。
4.MutiBoxTracebyChannel:本项目的核心节点。给定起点、终点创建一条线段,并沿给定的半径扫描,返回所有的 命中,输出的数据类型是OutHits——HitResult结构的数组形式,可以拆分成HitResult类型。用这个节点创造一个合理的射线,并给定合理的半径,我们就可以“选中”要旋转的小方块。
5.RotateVectorAroundAxis:令给定的向量绕一条轴旋转特定角度,返回旋转后的向量。
6.TimeLine:新建一条时间线,随时间输出一个数值,可以双击调整。输出频率是帧。
有了这些新节点,我们就可以开始着手构建第一个项目。
魔方的实现
1.首先,我们要创造出一个魔方。运用ForLoop循环和AddStaticMeshComponent就可以轻松实现。需要注意的是,创造出的小方块的中心点是小方块物体的中心,计算坐标偏移时以中心点为目标。
2.最重要的一步莫过于设计一个合理的射线,令MutiBoxTracebyChannel返回我们需要的即将旋转的小方块组合。事实上,我们只需要令射线长与宽的半径足够大,涵盖这一层所有的小方块,再令高度足够小,不会同时扫描两排的小方块即可。至于选择哪一层的小方块,可以通过起点、终点的位置来调整,这里我们为了方便可以直接令起点和终点在同一地点。
3.小方块的旋转可以拆解成两部分。第一部分就是绕坐标轴的“公转”,小方块经过旋转来到全新的坐标,这个新坐标我们通过RotateVectorAroundAxis计算得出。第二部分是小方块伴随着公转进行“自转”,相对自己的坐标轴做与公转同方向的旋转,以此来达到“相对静止”的效果。
下面,我们给出基于以上思路的蓝图。