‫嘿, 你好
‫欢迎回来｡
‫我们已经创建了一个基类—-C++类｡
‫在本视频中, 我们将从该类派生, 以基于base-—创建一个新子类｡
‫所以让我们来讨论一下为什么我们要这么做｡
‫我们有一个基类, 我们知道我们会有两个不同的类从基类派生出来.
‫我们会有我们的坦克, 我们会有塔｡
‫现在, 底部——包含网格, 一个胶囊以及一个产卵点｡
‫而这些都是坦克和塔都可以继承的东西｡
‫但坦克和塔也将有一些功能, 彼此不同｡
‫首先, 我们的坦克将在世界各地移动, 它也将由玩家控制｡
‫因此, 需要将其配置为从键盘和鼠标接收输入｡
‫而塔, 则是坐在那里｡
‫它不需要玩家的任何输入, 因为它的动作都将由代码控制｡
‫因为坦克和塔的行为不同,
‫我们将利用继承来创建基类的子类——这样我们就可以继承它们的共同点, 然后为每个类添加那些不同的特性｡
‫我们回到了编辑器, 我将进入C++类, TuneTank的文件夹,
‫我们在那里有基类, 这就是我们要从中派生的类.
‫现在, 我们可以右键单击此处并选择“创建从base派生的C++类”——｡
‫让我们选择它, 我将允许它把这个类粘贴到与base相同的源代码, tune tank文件夹中｡
‫至于它的名字, 我就叫它坦克｡
‫所以我们的坦克类将是我们真正的坦克的类——我们在世界上控制和移动｡
‫因此, 让我们单击“创建类”｡
‫好了, 我们已经编译了, vs代码已经打开了, 有了新的坦克文件, 还有坦克CP｡
‫现在这些都是光秃秃的｡
‫这里什么都没有, 虽然我们看不到它们, 但我们从基类继承了一些东西.
‫我们确实有那些添加到基础中的组件——｡
‫即使这些是私有变量, 它们仍然存在于这个类中｡
‫现在我们已经创建了坦克类, 让我们来讨论几件事.
‫坦克需要炮塔不需要｡
‫既然我们要控制坦克, 我们需要一种方法来关注坦克, 因为它在整个关卡中滚动｡
‫在这张照片中, 这是一个摄像头组件｡
‫它的C++类是摄像头组件｡
‫这条红线叫做弹簧臂组件, 它的C++类就是弹簧臂组件.
‫把这些部件加到一个——让我们可以从摄像机的角度来观察——｡
‫如果摄像机和它的弹簧臂以某种方式连接到......, 它们会跟随......在世界各地｡
‫现在, 回到编辑器中, 如果我们返回到——的文件夹并打开BP--tank, 我们可以单击视口,
‫这样我们就可以看到所有内容｡
‫然后, 我们可以选择胶囊组件, 单击添加并选择弹簧臂｡
‫这是一个弹簧臂组件｡
‫它看起来像一条红线｡
‫现在, 选择弹簧臂组件后, 我们可以添加另一个组件并选择相机｡
‫现在, 我们将摄像头连接到弹簧臂上, 一旦我们开始控制,
‫我们就可以从摄像头的角度进行观察了｡
‫现在弹簧臂非常有用｡
‫它有这个目标臂长度, 如果你调整它, 你会看到摄影机随着弹簧臂一起调整｡
‫所以这是一种控制摄像机距离的方法——｡
‫这些肯定是我们需要的, 类, 但我们将从C++端添加它们,
‫而不仅仅是在蓝图中添加.
‫所以我要把它们删掉｡
‫所以作为你们的挑战, 我希望你们能在坦克课上增加一些东西｡
‫首先, 我们需要一个弹簧臂组件和一个摄像头组件, 所以创建这些变量并将它们作为指针｡
‫继续创建一个公共部分和一个私有部分, 并将这些变量放在私有部分中｡
‫现在我们需要这些是U属性, 所以给予它们属性宏, 并根据前面课程中学到的内容,
‫在这些宏中填入适当的说明符｡
‫现在, 一旦你创建了这些变量, 创建一个构造函数,
‫把它放在公共部分, 并在CP文件中定义它, 然后在构造函数中使用create default
‫sub对象构造我们的相机和弹簧臂组件｡
‫请确保使用安装附件将这些组件连接到某个东西上｡
‫我们希望将弹簧臂组件附加到根组件｡
‫因此, 使用根组件并设置安装附件, 对于摄像机, 将其连接到弹簧臂｡
‫您可以指涉回基底类别｡
‫A提醒自己做这些事情的代码是什么样子的｡
‫继续暂停视频并将这些内容添加到坦克类中｡
‫好吧, 我会的
‫所以我们在坦克｡
‫现在, 先说正事｡
‫我想要一个公共区和一个私人区.
‫因此, 我们将在private部分添加这两个新组件｡
‫我们需要一个U形弹簧臂组件, 它是一个指针, 我们可以称之为弹簧臂｡
‫我们还需要一个新的摄像头组件, 我们称之为摄像头｡
‫没关系, 我会的
‫如果你们的名字稍有不同｡
‫现在, 马上, 我在这里看到了IntelliSense错误, 这意味着我需要向前声明这些错误｡
‫所以我要用弹簧臂和摄像头｡
‫现在这些都是正向声明的｡
‫现在我们需要新的房产｡
‫因此, 让我们添加新的属性宏｡
‫在属性宏中, 我们需要一些说明符.
‫这些参数在任何位置都是可见的, 因为我们看到组件需要在任何位置都是可见的,
‫以便我们能够在详细信息面板中调整它们的参数｡
‫现在, 我没有看到任何立即需要暴露到事件图, 所以我认为我们不需要蓝图读取､
‫写入或蓝图只读｡
‫没关系, 我会的
‫如果您添加了它们, 我现在将忽略它们｡
‫我将给予这些分类｡
‫由于这些都是组件, 我将把它们与其他组件沿着放在组件类别中｡
‫现在, 我没有将它们公开给事件图, 所以我不需要在这里指定梅塔allow private access｡
‫这对于弹簧臂来说已经足够了, 我想给予摄像头组件赋予相同的属性｡
‫所以我把它复制过来｡
‫现在我们有了组件｡
‫接下来要做的是在构造函数中构造它们, 这意味着我们需要一个构造函数｡
‫现在构造函数的名字和类的名字一样, 所以它是一个tank, 我们需要在CP文件中定义这个构造函数.
‫所以让我们去坦克指挥所, 并创建一个坦克｡
‫这就是我们的函数体, tank构造函数必须以类名和作用域解析操作符作为前缀｡
‫就是这里的双冒号
‫这样我们就不仅仅是创建了一个新函数, 而是定义了这个类的构造函数｡
‫现在, 我们要构建这些组件｡
‫让我们从弹簧臂开始｡
‫所以我们要说弹簧臂等于创建默认子对象, 这将是一个u弹簧臂组件｡
‫至于文本, 我就简单地称之为弹簧臂｡
‫对于附件, 我们将设置弹簧臂, 设置附件, 传入根组件｡
‫现在就去
‫我一直在等｡
‫就在那儿｡
‫IntelliSense错误指出指向不完整类类型的指针使用了spring arm组件｡
‫这是因为我们需要包含头文件, 因为我们要创建和使用弹簧臂组件｡
‫这是我的虚幻引擎文档, 如果我向下滚动, 这是我的包含｡
‫我将复制并粘贴到顶部, 就在水箱边缘下面.
‫现在, 只是一个侧记, 一般来说, 你要把你的类头文件放在顶部,
‫把你的组件的包含放在下面｡
‫我们有了弹簧臂｡
‫是时候组装摄像机了｡
‫所以我们要说创建默认的子对象, 摄像机组件｡
‫在文本宏中, 我将把它简单地称为相机｡
‫对于相机, 我将调用安装附件, 通过弹簧臂｡
‫当然我需要相机头文件｡
‫这是虚幻引擎文档,
‫这里是搜索文档, 我将输入摄像头组件, 这里是摄像头组件｡
‫我会选择它｡
‫这是摄像头组件的文档｡
‫所以我会把它复制粘贴到文件的顶部｡
‫现在我们应该没事了｡
‫好的, 让我们继续编译这个｡
‫好吧, 我会的
‫所以我有一个成功的编译｡
‫让我们回到编辑器, 然后回到坦克.
‫当然, 我们什么都看不到, 因为tank是从base派生的我们刚添加的组件,
‫我们添加到了tank类中.
‫所以BP--tank不会得到这些, 因为它不是从tank类派生的.
‫现在, 我们可以根据坦克类创建一个新的蓝图, 但之后我们必须重新设置这些组件｡
‫我真的不想再经历一次｡
‫我们有一个更简单的方法可以把这个蓝图修复到坦克类｡
‫我们通过转到类设置来实现这一点, 在选中类设置的详细信息面板中, 我们可以看到类选项,
‫其中有一个父类｡
‫下拉列表显示它被设置为base upon, 但是如果我们单击它,
‫我们可以搜索tank并选择tank作为基类｡
‫而现在这个蓝图就是从坦克类衍生出来的｡
‫我们可以看到, 我们为组件设置的所有属性（如网格和胶囊大小）仍然存在｡
‫只是现在我们看到了摄像机｡
‫事实上, 我们有一个弹簧臂和一个摄像头｡
‫如果我们现在选择弹簧臂, 我们可以看到那条红线｡
‫所以这是伟大的｡
‫因此, 我可以使用此弹簧臂组件并更改其目标臂长度｡
‫如果我喜欢, 我可以把它设置为600, 我甚至可以改变它的旋转,
‫使它的角度相机在坦克下选择旋转模式和旋转了一点｡
‫就像, 所以现在我想指出的是, 你不应该改变摄像机的位置｡
‫选择摄影机并将其在世界上四处移动, 以便正确定位和调整角度, 这可能很有吸引力｡
‫但这不是正确的做法｡
‫正确的方法是设置弹簧臂零部件的旋转和目标臂长度｡
‫原因是你想把摄像机连接到弹簧臂的末端｡
‫弹簧臂有很多不同的内置功能,
‫如当相机撞到墙上以避开障碍物时收缩, 挡住池塘的视线等｡
‫所以你要把摄像机连接到弹簧臂的末端, 然后调整弹簧臂,
‫而不是调整摄像机的位置和旋转｡
‫因此, 在本视频中, 我们创建了tank类, 并从base pond派生, 以继承base
‫pond类的这些特性｡
‫我们添加了一个弹簧臂组件和一个摄像头组件, 并使用visible only将它们暴露给编辑器,
‫并将它们放在各自的类别中｡
‫所以我们一步一步的接近成品, 我们会在下一节课继续开发这个水箱｡
‫我很快就会见到你的｡