《精通Unreal游戏引擎》一第9步 第一行代码

简介:

本节书摘来异步社区《精通Unreal游戏引擎》一书中的第9步,作者: 【英】Ryan Shah(沙哈)译者: 王晓慧 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。

第9步 第一行代码

精通Unreal游戏引擎
当前我们位于Graph(图表)视图,是时候进行一些有趣的操作了。

重要提示:
本书从现在起,当我告诉您要创建一个节点时,默认是使用Compact Blueprint Library(CBL)来搜索和创建(除非额外说明)。右键(Mac上是Ctrl键+鼠标左键)单击蓝图Graph(图表)视图空白处打开CBL,在Search(搜索)框中输入节点名称。
首先,我们需要一个Tick事件。什么是事件和Tick事件?

什么是Event(事件)?蓝图中的事件正如字面意思所描述的,就是发生一个事件。如果蓝图中没有事件,那么任何事情都不会发生。例如,想一下宇宙大爆炸原理:一旦宇宙大爆炸事件发生,那么各式各样的Action(动作)会因此发生。如果没有动作连接到蓝图的事件,那么就不会触发该动作,也不会执行该动作。

当创建蓝图的时候,记住在蓝图动作发生之前,要先发生事件。您可以通过如下简单的方式来区分蓝图中的Event(事件)节点和Action(动作)节点:事件只有输出引脚(通常在右边),用红色表示;而动作有输入引脚和输出引脚,用蓝色表示。

所以,红色 = Event(事件),蓝色 = Action(动作)。

什么是Tick事件?Tick事件是指在游戏时间的每一帧都被触发的事件。游戏开发的新手可能不明白这是什么意思,特别是帧和秒的区别。但是多数人知道一帧不等于一秒,它比一秒要快。

您曾经测试过一个游戏的性能吗,或者有意购买达到一定FPS(Frame Per Second)游戏的电脑部件?回想一下,当讨论游戏时,会经常提到过30FPS或60FPS。触发Tick事件是一帧,所以60FPS是指触发连接到它的60个Tick事件。

我们已经学习了什么是Tick事件,现在就使用Tick事件控制摄像机的位置,让它对准玩家。

下面从何开始呢?蓝图的脚本从哪里开始?从事件开始!针对当前需求,我们使用刚刚学习的Tick事件。

在开始编写脚本之前,确认现在位于脚本界面的正确区域。在Debug filter(调试过滤)区域可以查看所在的区域,您会看到两个选项卡:Construction Script和Event Graph(事件图表),如图65所示。

Construction Script选项卡是编写蓝图初始化代码的地方。例如,设置蓝图的Mesh(网格对象),告诉蓝图在特定情况下的行为,等等。

Event Graph(事件图表),如图66所示,是编写由事件所触发的代码的地方。这些代码既可以被当前蓝图触发,也可以被另外一个蓝图远程触发。


65_66

经验表明,90%的情况下您会使用EventGraph(事件图表)选项卡,因为Construction Script选项卡不能与游戏世界及其他蓝图进行交互,但是在EventGraph(事件图表)选项卡中可以。您可以在这两个选项卡之间切换。如果选项卡的图标颜色为浅灰色,说明可以选择该选项卡。如果为深灰色,意思是该选项卡没有被激活。

正如前面所说,我们需要一个事件,因为如果没有触发事件,就不能执行任何代码。这里需要每一帧都触发一段代码,所以使用Tick事件。

下面在Event Graph(事件图表)选项卡中创建Tick节点。右键(Mac上是Ctrl键+鼠标左键)单击蓝图Graph(图表)视图空白处,打开CBL(Compact Blueprint Library),人工寻找或者在Search(搜索)框中输入节点名称,如图67所示。


67

单击Event Tick(事件Tick)来新建节点,如图68所示。


68

下面我们解释一下节点上所有图标的含义。

首先,您会注意到文本Event Tick(事件Tick)的背景是红色,意思是这是一个Event(事件),而不是Action(动作)。此外,文本Event Tick(事件Tick)左边有一个中间含有箭头的菱形图标,也是用来标识这是一个事件的。

其次,您还会观察到文本Event Tick(事件Tick)的右边有一个镶有亮红色边框的黑色正方形。这个图标的含义是Output Delegate(输出委托)。我之后再解释它的意思,因为涉及很多现在还没有讲解到的知识。

在红色背景的下方有两个图标,一个指向右边的空箭头和一个指向右边的绿色空圆圈。在解释它们的含义之前,注意它们的位置。对于节点来说,输入和输出是通过它们在节点中的位置来区分的。左边的是输入,右边的是输出。这将帮助您来区分节点是事件还是动作,事件只有输出(也就是只有在右边的图标),而动作既有在左边的图标也有在右边的图标。

扼要重述一下:节点左边的图标表示输入,右边的图标表示输出。

与输出连接的是什么呢?输入。例如,将键盘的USB插入到电脑的USB接口上。把敲击键盘看作是一个事件,这个事件触发的行为通过USB接口输出到电脑。

上述这个例子很好地说明了蓝图的工作原理:事件>事件输出>动作输入>动作。但是这里缺少了一个重要的东西——事件>动作的关键因素,就是execution pin(执行引脚)。Event Tick(事件Tick)节点的红色背景下方有两个图标,其中一个是白色的空心箭头图标,就是这里所说的执行引脚。

执行引脚到底是什么呢?执行引脚就是操作的脉络,它将事件的能量传递给与它连接的节点。例如,事件节点是一个完整的电路,而动作节点是缺少了电源的电路,您可以使用事件的执行引脚输出能量给动作节点使其工作。那么如果有两个动作节点呢?没问题。虽然动作节点需要从事件节点传递的能量,但是它不需要对这个能量做任何操作,仅仅用来确认“我收到信号了,现在可以运行了”。所以如果让两个动作节点同时工作,就将一个事件节点通过执行引脚连接到其中一个动作节点,再将另外一个动作节点连接到这个动作节点的输出,它们将同时使用事件节点的能量(因为没有能量丢失)。

下面我们来实际操作一下。首先新建一个我们需要的节点。因为摄像机总是面向玩家,所以新建节点Set World Rotation。将这个节点与一个Event Tick(事件Tick)节点连接,用来改变每一帧摄像机的角度。

新建Set World Rotation节点。如果您使用的是4.6或以上版本的Unreal,将会在CBL中看到“Set World Rotation (Camera1)”(或者是您的摄像机名称),如图69所示。


69

注意:
如果您使用的是低于版本4.6的Unreal Engine,您看到的是Set World Rotation,需要手动设置Camera1,通过将Camera1(在蓝图视图左边的变量库中)拖拽到新建节点的Target(对象)引脚上。在一些更老的版本中,需要您将Camera1从变量库中拖入,然后从Target(对象)引脚向外拖拽,再输入Set World Rotation。
如果使用的是4.6或以上版本,直接右键(Mac上是Ctrl键+鼠标左键)单击打开Compact Blueprint Library,搜索Set World Rotation,然后选择Set World Rotation (Camera1)。

新建的Set World Rotation节点如图70所示。

正如之前所说,动作是与事件相连的。具体操作是将Event Tick(事件Tick)节点的输出执行引脚与Set World Rotation (Camera1)的输入执行引脚相连,如图71所示。当空心的执行引脚被白色填充,同时两个引脚之间有一条线相连时,说明已经建立了连接关系。


71

下面我们将设置每一帧摄像机的World Rotation(旋转角度)。仔细观察刚刚创建的节点,发现我们需要计算出摄像机的角度(当前是Roll = 0,Pos = 0,Yaw = 0),以便摄像机跟着玩家旋转。

下面用代码来实现摄像机跟随玩家。当前我们要创建的对象没有执行引脚,这和我们之前讲解的内容完全不同,这是因为我们将要创建的不是动作节点。创建完后面的代码,我们再回来解释它是怎么工作的。

下面将要编写的这段代码连接到Set World Rotation (Camera1)的New Rotation。注意要保证蓝图有足够大的空间,否则因为蓝图中有许多线交叉连接,很快会使代码变得杂乱难读。

在编写蓝图代码之前,前往左边的变量库,在Components(组件)下面找到Camera1(或者是您的摄像机名字),如图72所示。


72

单击文本Camera1,将这个变量拖入到蓝图中。此时将弹出一个小菜单,询问是Get(获得)还是Set(设置),如图73所示。意思是获得变量,还是设置变量。在当前情况下,它是一个新的摄像机Actor,所以选择Get(获得)。


73

选择Get(获得)之后,蓝图中将出现一个蓝色底的圆角矩形,并且带有一个蓝色的输出引脚,如图74所示。如果您看到的不一样,说明您在从变量库中拖入Camera 1变量时,选择的不是Get(获得),应返回重新操作。


74

单击Camera 1节点上的蓝色输出引脚,向右拖拽,这时将打开Compact Blueprint Library。由于我们需要摄像机的旋转角度,所以输入Get World Rotation,如图75所示。


75

找到Get World Rotation节点之后,单击新建节点,如图76所示。当前这个节点应该已经与Camera1建立了连接,如果没有,要先建立连接。


76

我们得到了游戏世界中摄像机的旋转信息,例如它是绕X轴旋转45°,绕Y轴旋转51°,可以用Rot(X) = 45,Rot(Y) = 51来表示。但是在我们的例子中只需要知道旋转后X轴的方向,就可以轻松跟踪摄像机当前的朝向。

使用CBL新建一个Get Rotation XVector节点,将其连接到Get World Rotation节点的输出引脚,如图77所示。


77

现在,我们获得了摄像机X轴的朝向信息。从技术角度来讲,因为还没有连接到事件的主要链条上,所以此刻还不能工作,但是理论上,一旦与事件的主要链条连接上,我们就可以获得摄像机的信息。目前这些只是摄像机跟随玩家这个功能的部分代码。

下面我们将目前收集到的信息(摄像机的X向量值)连接起来,让摄像机跟着移动。但是我们希望摄像机的移动轨迹平滑一些,使用VInterp To节点实现这一功能。该节点可以创建两个值之间的平滑过渡。

使用Compact Blueprint Library新建VInterp To节点(注意不是VInterp To Constant),将其Current引脚与Get Rotation XVector节点的输出引脚相连,如图78所示。


78

VInterp To节点有3个输入,需要设置好这3个值才算完成了这个节点的创建。我们一会儿再讨论Target输入,先关注Delta Time 和 Interp Speed这两个输入。设置Interp Speed为0.01,意思是每隔0.01的Delta Time(我们一会解释它的意思)就更新当前的Rotation(旋转)值,并将其赋值给Target。设置VInterp To节点的Interp Speed值为0.01,如图79所示。


79

有两种方式设置Delta Time值,我们先解释一下什么是Delta Time。

Delta Time是从上一个Tick(或者上一帧)到此刻所经历的时间。还记得我们之前见过Delta Time吗?它曾在Event Tick节点中出现。

有两种方式连接到Event Tick节点的Delta Time,单击Event Tick节点的Delta Time输出,拖拽到Vinterp To节点的Delta Time输入,如图80所示。


80

从图80可以看出,构建的蓝图特别凌乱。虽然现在还不是问题,但是当我们创建更复杂的蓝图时,就很难分辨出这些节点之间的连接关系了。

所以,我们将Delta Time存储为一个变量,这不仅能使蓝图更清晰,还可以随时使用Delta Time。我知道有些读者可能会说这样意义不大,但是实际上将Delta Time转变为一个变量有很多好处:

1.保持蓝图代码清晰、可读性强;

2.有助于多次使用Delta Time值;

3.有助于将一些蓝图节点拆封成单独的图(之后会讲解到);

4.清晰整齐的蓝图意味着清晰的思路。

如果两个Delta Time已经连接,那么断开连接。具体操作是Alt键+鼠标左键单击连接的任意一端引脚,下面采用更恰当的操作方式。

感谢版本4.6的改进,现在有一种特别简单的方式将Delta Time转变为变量,之后就可以随时使用Delta Time了。

在4.6或以上版本,右键(Mac上是Ctrl键+鼠标左键)单击Event Tick节点的Delta Time的输出引脚,选择Promote to Variable(提升为变量),新建一个Set New Var(设置New Var)节点,如图81所示。同时在界面左边的变量库中也新建了一个NewVar变量。


81

需要注意几点。首先,您会看到Set World Rotation节点中出现“ERROR!”。别担心,这不是错误。只需要单击蓝图视图中工具栏左上方的Compile(编译)按钮(图标是两个齿轮上面有一个画有问号的矩形框),重新编译一下,这个问题就解决了。

其次,Set New Var(设置New Var)节点没有与事件的主要链条(或者说是蓝图的能量线)相连。Alt键+鼠标左键单击Event Tick的输出执行引脚或者Set World Rotation节点的输入执行引脚,断开连接,然后将Event Tick的输出与Set New Var(设置New Var)节点的输入相连,Set New Var(设置New Var)节点的输出与Set World Rotation节点的输入相连,如图82所示。


82

Delta Seconds是基于时间的变量,这一步操作是保证对于每一帧,我们在进行任何操作之前都先设置Delta Seconds,这对于后面获取Delta Seconds值至关重要。

最后一个问题是变量的命名。因为很容易忘记New Var表示什么,所以将其命名,以方便记忆。前往蓝图视图左边的变量库,单击新建的New Var变量,在Details(细节)面板中出现该变量的各种选项。其中第一个选项是Variable Name(变量名称),当前默认值是New Var。将New Var重命名为DT_DeltaTime,如图83所示。单击键盘上的Enter(回车)键,编译蓝图(单击工具栏左上方图标为贴有问号矩形框的两个齿轮的按钮)。编译完成后,单击编译按钮右边的Save(保存)按钮,保存上述操作。


83

如果您使用的是Unreal Engine 4的旧版本(低于4.6),就不能直接对Event Tick节点的Delta Time使用Promote to Variable(提升为变量)。而是要在变量库中手动创建变量,设置其为浮点数(稍后解释原因),将其拖拽到蓝图中并选择Set(设置)。设置好之后,重复之前的步骤连接到执行主链上。在版本4.6之前,您还需要进行一步操作:从Event Tick节点的Delta Time引脚拖出,连接到Set New Var / DT_DeltaTime节点的输入引脚。但是如果使用的是版本4.6或以上,使用Promote to Variable(提升为变量)可以跳过这一步。

现在已经有了DT_DeltaTime变量,将变量库中的DT_DeltaTime变量拖到VInterp To节点DeltaTime引脚的上面,或者将DT_DeltaTime变量拖到蓝图区域,选择Get(获得)选项,然后将其与VInterp To节点的DeltaTime引脚相连,如图84所示。


84

现在,我们来处理VInterp To节点的Target输入。Target的作用很明显,是输入Current的变换目标。举例来解释:如果Current是1,Target是5,VInterp节点利用Delta Time 和 Interp Speed生成1到5的序列。因为每一秒触发一次,所以可以保证平滑过渡,避免抖动。

新建用于Target输入引脚的节点,将变量库中的变量Camera 1(或者是您摄像机的名称)拖入到蓝图区域,选择Get(获得)选项,如图85所示。


85

右键(Mac上是Ctrl键+鼠标左键)单击打开CBL,输入Get Player,选择Get Player Character,如图86所示。

86

现在得到了一个可以调用游戏当前玩家的节点和对应的Player Blueprint(玩家蓝图,稍后将详细解释),如图87所示。


87

下面需要得到它们在游戏世界中的位置。打开CBL,输入Get Actor搜索得到Get Actor Location节点。将该节点的输入与Get Player Character节点的Return Value引脚相连,如图88所示。


88

单击刚才创建的Camera 1节点的输出引脚,向右拖拽打开Compact Blueprint Library,输入Get World搜索,选择Get World Location,如图89所示。


89

现在已经得到了摄像机和玩家在游戏世界中的位置信息(因为我们使用的是Tick事件,所以每一帧都会更新这些信息)。下面让这两个位置相减。为什么呢?因为我们不希望摄像机紧跟着玩家,而是两者之间保持一定的距离,摄像机和玩家之间的距离向量将提供平滑的显示效果,在玩家突然做一个动作(如跳高或者快速转身)时,摄像机不会跟着玩家快速移动。

打开CBL,输入Vector,选择Vector – Vector,如图90所示。


90

Vector – Vector节点有两个输入和一个输出,将Get Actor Location的输出与Vector – Vector节点中的一个输入相连,Get World Location的输出与另外一个输入相连,如图91所示。


91

将Vector – Vector节点的输出连接到VInterp To节点的Target输入,如图92所示。


92

现在,已经得到了摄像机的旋转信息,并且通过玩家和摄像机之间的平滑变换对其赋值。

下面将之前计算的旋转进行分解,得到其中的pitch和yaw值(上下及四周旋转分量),并加以截断限制,防止旋转的角度过大。对这些值进行截断限制之后,重新计算得到一个旋转值,作为之前创建的Set World Rotation节点的输入。

我发现刚才的操作中有一个错误。如果不纠正这个错误,摄像机将背离玩家,而不是面向玩家。请您花一点儿时间仔细查看代码,尝试找到错误的位置。

现在我们在它成为一个真正的问题之前,快速找到并解决它。先来思考一个数学问题,有两个数100和51,让它们做减法。可以100 − 51 = 49或者51−100 = −49。由于这两个数的先后位置不同,结果截然不同。

现在,回到获取Camera(摄像机)位置和Player Controller(玩家控制器)位置这部分代码。这两个值相减之后的结果是VInterp To节点的Target输入,如图93所示。

您的摄像机的Get World Location是与Vector – Vector节点的第一个输入引脚相连吗?如果是,说明您准确无误地跟着本书的讲解步骤,但是这里仍包含一个错误!很庆幸在它成为一个真正问题之前,我把它指出来了。这是一个很好的机会,让大家看到这个步骤是多么容易混淆,容易发生错误。

假如我们得到的摄像机的值是X=51、Y=11和Z=22,减去玩家的坐标值。因为玩家距离更远一些,所以它的坐标值往往比摄像机的坐标值大,例如X=151、Y=211、Z=512。如果这两者做减法,将得到一个负值。这意味着什么呢?这导致的效果是摄像机将远离玩家,而不是面朝向他。


93

那么如何解决这个问题呢?很简单!将玩家的Get Actor Location节点与Vector – Vector节点的上方输入相连,摄像机的Get World Location节点与Vector – Vector节点的下方输入相连,如图94所示。


94

解决了这个问题为我们后面节省了大量的时间,不用为出现类似于“为什么运行不对”这样的错误而烦恼了。

总之,解决完这个问题,我们继续编写代码。现在需要使用VInterp To节点的输出重新设置旋转。右键(Mac上是Ctrl键+鼠标左键)单击打开CBL,输入Make Rot,选择Make Rot from X,如图95所示。


95

将新建的Make Rot from X节点的X输入与VInterp To节点的输出相连,如图96所示。

96

现在,我们已经得到了旋转信息,它由X轴转向信息计算而得。下面将对旋转进行分解,对其中的pitch和yaw分量进行限制。为什么呢?我们之前提到过,这么做是为了确保摄像机在一定的范围内旋转从而不会失去控制。

图97是一幅草图,来解释它是什么意思:假设最外围的矩形框是地图区域,底部中间的矩形是摄像机,顶部中间的黑点是玩家,中间的锥形区域是我们希望摄像机关注的区域,而两边的锥形区域是不希望摄像机拍摄的地方。


97

现在摄像机已经被准确控制了。等到最后完成这个项目,效果就会清晰地呈现出来。

现在需要分解前面获得的旋转。前往Compact Blueprint Library新建Break Rot(而不是Break Rot into axes)节点,将其与Make Rot from X节点的输出相连,如图98所示。

新建两个Clamp Angle节点,在搜索框中输入Clamp Angle得到常用的Clamps(不是Clamp [Float]),如图99所示。

将Break Rot节点的Pitch输出与上面的Clamp Angle节点的Angle Degrees输入相连,将Break Rot节点的Yaw输出连接到下面的Clamp Angle节点的Angle Degrees输入,如图100所示。


98_99_100

为了计算这两个Clamp angle的Min / Max Angle Degrees值,需要做一点点数学运算。别担心,我们不需要计算出结果,仅仅列出等式即可。我们将在等式中使用Pitch和Yaw这两个值和一个常数80。为什么选择80呢?意思是摄像机在面向玩家时,限制摄像机的角度在−80°到+80°之间,也就是我们希望摄像机关注的160°区域(这样设置是为了不让其关注整个屏幕,同时避免玩家突然运动时,摄像机找不到他)。

有两种方式将常数80加入到我们的蓝图中。一种是使用Make Literal Float节点,另一种方式是在变量库中新建一个Variable(变量,Float类型,即浮点类型的变量),设置其Default Value(默认值)为80。注意新建变量之后,Compile(编译)并Save(保存)之后就可以设置变量的Default Value(默认值)了。

根据您的个人喜好选择一种方式。我在这里新建Make Literal Float节点,并设置它的值为80。然后将Variable(变量)或者Make Literal Float节点复制4次,如图101所示。


101

新建两个Float – Float节点和两个Float + Float节点。将这4个节点与Make Literal Float节点(或者您的变量节点)相连,注意是将Make Literal Float节点(或者您的变量节点)连接到Plus / Minus(−/+)节点的第二个输入。

下面将第一个和第三个Make Literal Float节点(或者您的变量节点)连接到两个Float – Float节点的第二个输入,如图102所示。


102

将第二个和第四个Make Literal Float节点(或者您的变量节点)连接到两个Float+ Float节点的第二个输入,如图103所示。


103


如果您看不清这些图片,记得从http://www.kitatus.co.uk免费下载本书插图的高清版本。再次确认您的蓝图中,4个Make Literal Float节点或者变量节点的连接方式如下:

1.Make Literal Float节点/变量节点>Minus(−)节点的第二个输入;

2.Make Literal Float节点/变量节点> Plus(+)节点的第二个输入;

3.Make Literal Float节点/变量节点>Minus(−)节点的第二个输入;

4.Make Literal Float节点/变量节点> Plus(+)节点的第二个输入。

下面回到Break Rot节点,虽然该节点的Pitch和Yaw输出已经与两个Clamp Angle节点的输入连接了,我们仍然可以将其与其他输入连接,即可以一个输出同时与多个输入相连。

下面将第一个Minus(-)节点和第一个Plus(+)节点的第一个输入与Break Rot节点的Pitch输出相连,第二个Minus(-)节点和第二个Plus(+)节点的第一个输入连接到Break Rot节点的Yaw输出,如图104所示。


104

现在设置这些Minus(-)和Plus(+)节点的输出。下面列出Clamp Angle节点的Min Angle Degrees / Max Angle Degrees输入的连接方式,如图105所示。


105

1.第一个Minus(-)节点的输出连接到第一个Clamp Angles节点的Min Angle Degrees引脚;

2.第一个Plus(+)节点的输出连接到第一个Clamp Angles节点的Max Angle Degrees引脚;

3.第二个Minus(-)节点的输出连接到第二个Clamp Angles节点的Min Angle Degrees引脚;

4.第二个Plus(+)节点的输出连接到第二个Clamp Angles节点的Max Angle Degrees引脚。

我们的蓝图看起来有点像一份美味的意大利面汤了。只要您跟着我的步骤操作,一切都会很顺利的。我们很快就要完成这个蓝图了,下面利用这些信息为摄像机生成旋转。

右键(Mac上是Ctrl键+鼠标左键)单击打开Compact Blueprint Library,搜索Make Rot,选择新建Make Rot节点,如图106所示。


106

将第一个Clamp Angle节点的输出与新建的Make Rot节点的Pitch输入相连,将第二个Clamp Angle节点的输出与该Make Rot节点的Yaw输入相连,如图107所示。

最后,我们得到了一个旋转输出(通过引脚颜色可以知道当前正在处理的输出类型)。将Make Rot节点的Return Value输出与很久之前创建的Set World Rotation节点的New Rotation输入相连,如图108所示。

在完成这个蓝图之前,仅剩下两件事情!

前往Set World Location节点,单击节点下方的向下箭头,展示隐藏选项,如图109所示。


108

109

现在您会看到一个名为Sweep的选项,当前状态是Off(关闭)。单击空复选框激活这个选项,框中有一个勾号,如图110所示,说明Sweep已经被激活了。


110

Sweep是做什么用的呢?Sweep是用来保证,当摄像机被障碍物(例如墙)挡住时,它不会继续移动。

现在还剩下最后一件事情:编译和保存。编译按钮位于该窗口的左上方,图标是两个齿轮上面有一个矩形框。编译前,矩形框中是一个问号。编译完,矩形框中是一个勾号。

单击Compile(编译)按钮,编译完成后,单击Compile(编译)按钮右边的Save(保存)按钮,如图111所示。


111

这个蓝图已经完成。现在继续项目,关闭蓝图,返回到Unreal Engine 4的主窗口。此刻,我们虽然创建好了蓝图,但是还没有显示在场景中,也就是没有被激活。下面我们马上来测试它。

前往Content Browser(内容浏览器),将BP_Camera拖拽到场景中。您可以把它摆放在场景中的任何位置,只要玩家和视图没有被其他障碍物挡住即可。使用Transform(平移)工具设置摄像机的位置,直到您满意为止,如图112所示。


112

现在在Level Blueprint(关卡蓝图)中添加一些代码,将摄像机设置为Active(激活)状态。

什么是Level Blueprint(关卡蓝图)?Level Blueprint(关卡蓝图)是一种特殊的蓝图模式,适用于当前正在玩的关卡或者正在运行的地图。您可以在一个Level Blueprint(关卡蓝图)中嵌入代码来记录分数或者跟踪Actor的状态等。

在继续之前,确保BP_Camera已经摆放在了场景中。通过如下方法检查:选中摄像机,它的周围会出现橘黄色的边缘线,并且旁边出现Transform(平移)工具(通常在该对象的中间)。

单击场景视图上方工具栏中的Blueprints(蓝图)按钮,选择Open Level Blueprint(打开关卡蓝图),如图113所示。


113

单击Open Level Blueprint(打开关卡蓝图),打开关卡蓝图。右键(Mac上是Ctrl键+鼠标左键)单击打开CBL,如果场景中的BP_Camera处于选中状态,那么在Compact Blueprint Library的上方有一个Create a Reference to BP_Camera(创建一个到BP_Camera的引用)选项,如图114所示。单击创建一个场景中摄像机的引用节点。


114

如果您没有看到Create a Reference to BP_Camera(创建一个到BP_Camera的引用)选项,说明没有选中场景中的摄像机。那么,返回Unreal Engine主窗口,选中场景中创建的BP_Camera对象。重复之前的步骤,直到在Level Blueprint(关卡蓝图)中添加了BP_Camera的引用节点,如图115所示。


115

现在需要新建一个节点,用于接收BP_Camera节点的输出(BP_Camera节点上没有输入和执行引脚)。将要创建的这个节点现在对我们不可见。为了访问到这个节点,不得不暂时关闭CBL中的Context Sensitive(情境关联)。

什么是Context Sensitive(情境关联)?Context Sensitive(情境关联)是Compact Blueprint Library窗口中的一个按钮,功能是根据当前的情境自动过滤菜单中的选项。也就是说,因为在特定的情景下,可能只需要特定的节点,菜单中不显示所有的选项。

关闭Context Sensitive(情境关联)模式意味着,我们能看到所有可以放置在蓝图中的节点。这时CBL的视图看起来有些混乱,即使对经验丰富的蓝图专家也是如此,因此在不必要的情况下还是建议打开Context Sensitive(情境关联)模式。

下面打开Compact Blueprint Library,取消CBL右上角方框内的勾选,关闭Context Sensitive(情境关联)模式,如图116所示。


116

Context Sensitive(情境关联)已经关闭,在搜索框中输入Set View Target,选择Set View Target With Blend,如图117所示。


117

如图118所示,Set View Target With Blend节点看起来很复杂。但是一句话总结这个节点就是,Set View Target(With Blend)是一个设置当前活动摄像机的节点。


118


只需要关注该节点的3个引脚,输入执行引脚,Target引脚和New View Target引脚。注意到New View Target引脚就是待设置的新摄像机,所以将BP_Camera节点的输出与New View Target引脚相连,如图119所示。


119

Target引脚默认引用当前摄像机,这里我们想用BP_Camera来代替它。打开Compact Blueprint Library,重新勾选Context Sensitive(情境关联),输入Player,选择Get Player Controller创建节点。将Get Player Controller节点的输出与Set View Target with Blend节点的Target输入相连,如图120所示。


120

还有一步操作就要完成了。还记得最开始我们讲到蓝图时提到的内容吗?每一个动作需要有(或者至少有)一个事件触发。当前还没有任何事件连接到Set View Target With Blend节点,所以它将不会被触发。

打开CBL,输入Begin,选择Event Begin Play。每当游戏开始时,该事件就会被触发一次,这将很好地测试BP_Camera是否正常工作。

前往CBL新建Event Begin Play节点,将其输出执行引脚与Set View Target with Blend的输入执行引脚相连,如图121所示。


121

单击Compile(编译)和Save(保存)按钮,关闭该窗口。

下面测试摄像机是否正常工作!找到位于场景视图上面的工具栏(打开Level Blueprint的地方)中的Play按钮,单击其下拉箭头,选择New Editor Window选项,如图122所示,可以测试我们的项目。


122

测试项目时,您的BP_Camera应该可以正常工作。如果没有,请返回到本步骤的开始,确保所有的步骤正确完成。或者到http://www.kitatus.co.uk 中免费下载该项目文件,与你的项目做比较,下载文件名为“[LESSON1]ArtOfBP_01.zip”!

您已经完美地实现了第一个蓝图项目。现在在此基础上扩展一点,在地图上设置多个摄像机,营造一个真实的可以点击操作的3D场景。

别担心,我们不需要重新创建BP_Camera。基于我们之前创建摄像机的方式,BP_Camera可以被多次拖拽到场景中,只需进行少量修改,就可以轻松实现一个布置了多个活动摄像机的场景。

相关文章
|
2月前
winfrom实现简单计算器V2版本
winfrom实现简单计算器V2版本
14 0
winfrom实现简单计算器V2版本
|
4月前
|
算法 安全 图形学
Unity Hololens2开发|(十一)MRTK3 Solver(求解器)
Unity Hololens2开发|(十一)MRTK3 Solver(求解器)
|
5月前
|
定位技术 API 开发者
【Godot引擎开发】简单基础,外加一个小游戏DEMO
【Godot引擎开发】简单基础,外加一个小游戏DEMO
|
自然语言处理
Flutter — 仅用三个步骤就能帮你把文本变得炫酷!
觉得普通的文字太单调了?别着急,在我这,仅用三个步骤就能帮你把文字变得炫酷,又是朴实无华的一番操作🤣~
Flutter — 仅用三个步骤就能帮你把文本变得炫酷!