一、前言
首先感谢B站马克镇镇长的视频讲解清晰把很多细节都照顾到了,我本来自己做的时候没有视频说的那么细,参考他的全套系列视频之后完善了很多内容。
视频指路:https://www.bilibili.com/video/BV1s5411Y7Ry
感兴趣的朋友别忘了给这个视频一键三连。
如何利用UE4制作一个2D游戏,众所周知,UE4是EPIC为了方便自己开发FPS游戏而“顺便”研发的一个引擎,后期通过不断的完善成为了现在功能强大的游戏开发引擎,并且在GITHUB上面进行开源,可以拿到源码进行魔改,然后声称“自主研发”。
后期会挖一个坑如何魔改UE4引擎源码(需要一定的C++基础),不过那是后话,本系列内容是如何使用UE4的蓝图进行制作2D游戏,主要包括以下内容:
(一)——基础篇,介绍UE4的基础操作,以及需要用到的类
(二)——资源篇,介绍如何导入基础美术资源进行场景制作与动画制作
(三)——角色篇,如何制作属于自己的角色,并且添加属于自己的操作
(四)——NPC篇,在角色制作的基础上创造一些NPC角色并且产生对话,制造故事流程
(五)——战斗篇,制作基于UE4自带AI的敌人,进行回合制战斗。
(六)——计算篇,进行战斗完毕后要对人物的奖励进行结算
(七)——数据篇,利用服务器存储角色数据,并进行在线交互(额外内容,不影响结算可以跳过)
……后续有更新再编辑这里
前文指路:
(一)基础篇:https://blog.csdn.net/qq_33182045/article/details/117120658
(二) 资源篇:https://blog.csdn.net/qq_33182045/article/details/117227086
(三)角色篇:https://blog.csdn.net/qq_33182045/article/details/117256883
(四)NPC篇:https://blog.csdn.net/qq_33182045/article/details/117560734
(五)战斗篇:https://blog.csdn.net/qq_33182045/article/details/117596948
二、UE4引擎奶妈级教程,如何对战斗结果进行结算
1.没看过战斗篇的读者可以去看看,如何进入战斗参考那一篇文章,这一次我们来对战斗结果进行结算。首先判定胜利条件,只要敌人生命值低于0,就宣告战斗胜利,那么我们就定义一个custom_event,来判定胜利。
先决条件是获取敌人的当前生命值参数,如果小于等于0,就将它置为0,并显示胜利界面,然后展示获得的奖励,如图1所示
图1 战斗胜利界面
可以在图1看到我们是在战斗胜利的时候会有一些数值影响玩家的角色的,因为要涉及到后面有个功能,该功能可更换操作的角色,所以相应的数值我们和上一篇一样,存储在玩家控制器里面。可以新建一个结构体,用于存储角色的一些基础数据,比如生命值,勇敢值,善良值,幸福值等等,如图2所示
图2 创建枚举
然后这个枚举就可以通用,在每一个项目里面存储对应通用的结构,比如如果我赋值给当前玩家的控制器,就新建一个数据表格,调用这个枚举,如图3所示
图3 新建数据表格调用结构体
调用这个结构体之后,可以看到类似于数据库操作的,没错,这个就是一个单机数据库,用来存储对应的数据
图4 数据表结构截图
在存储有数据的基础上,在角色蓝图里面调用对应行的数据,不过这个后期我们才用得到
2.新建角色内部的属性数据
在这里新建一个字符串表格,命名为shuxing,结构如图5所示
图5 玩家属性表格
这个表格用用于在玩家控制器当中存储相应的角色基础数据,再将这个数据存储进入步骤1中新建的结构体当中,那么我们如何在别的事件当中操控这些元素呢,这里提供两个思路,一个是通用蓝图接口(BP interface)如图6所示,另一个是调用自定义方法(custom events)如图7所示。
图6 蓝图接口界面
图7 自定义方法界面
友情链接董国政大佬的蓝图接口详解https://blog.csdn.net/qq_36409711/article/details/76596206
3.蓝图接口我们后面会专门开一个别的栏目来讲,这里我们用自定义方法来进行数据操作,所有的数据和方法都在玩家控制器当中,所以我们战斗胜利的时候调用玩家控制器对象的同时可以调用对象内的自定义方法。
先判定战斗胜利,在战斗界面的UI图表方法中,新建一个自定义方法,命名为victory_event,当敌人血量为0以下时,判定战斗胜利,并告知玩家控制器你获得了胜利,让敌人消失,并且获得奖励结算,如图8所示
图8 战斗胜利自定义方法
当敌人死亡的时候,将敌人生命值置为0,并且让胜利计算界面可视,进行结果计算(结果计算方法自己写),然后调用玩家控制器,通知敌人死亡,调用敌人死亡方法,接着调用切换音乐方法,再结束战斗,结束战斗就是将当前战斗界面从父项移除。
4.然后回到玩家控制器界面,生成一个自定义方法,命名为update_shuxing,用于更新玩家控制器内的某个属性,输入“shuxingming”字符串来存储属性的下标,用作属性名,"shuxingdian"整数来用作属性增加的数值,比如我要让"brave"属性+2,就将"shuxingming"输入为“brave”,"shuxingdian"输入为2,然后通过ADD方法,将属性表中对应的brave属性+2,如图9所示,这里需要说明一下为什么用ADD,官方给的解释是添加一个数组元素,如果原数组当中已经有相应下标的数组元素,则将其覆盖,所以我们引用了这个元素加上新的值之后覆盖原值。
图9 增加属性值通用方法
5.定义敌人死亡方法,以及战斗结束之后对属性的影响,首先我们定义敌人死亡的方法,当UI界面告诉玩家控制器敌人已经死亡的时候,玩家控制器当中存储的敌人生命值也相应的置为0,然后因为战斗胜利,需要获取更新属性,就调用刚才写的update_shuxing方法,输入brave,2,战胜敌人之后原地生成一个ACTOR,因为策划的要求是生成一个宝箱,而宝箱类我还没做,所以先用做好的NPC代替,接着敌人被销毁,如图10所示
图10 角色死亡方法
这样就进行了战斗胜利——增加角色属性——NPC消失——打开宝箱这么一个过程。
6.同样的道理,策划同学给了我一个要求,当某个属性增加了三次之后,会有进阶属性,那么我们重复之前1-4步的操作,来新建一个进阶属性数据表,并且用整形切换来进行数值的切换。如图11所示
图11 进阶数据添加
保存好蓝图后进行编译。
这样基础属性的计算和进阶属性的计算我们也就完成了,然后我们来测试一下效果,完成战斗之后是否能输出进阶的属性。初始属性如图12左上角、图13左上角所示。
图12 角色初始属性
图13 角色战斗胜利之后的属性
可以看到其中一项28的数据变成了30,说明了战斗胜利brave属性增加了2,而其他属性不变,方法调用成功。
三、总结
本次的文档重点讲了如何调用方法来进行计算,讲了蓝图接口与自定义方法两个类型的类,重点强调自定义方法的编写与调用,其实学会活学活用面向对象编程,每一个子功能进行分割,制作高内聚,低耦合的对象方法,可以让日后在扩展和维护的时候更方便与快捷,减少错误率,如果有需要我会专门出一篇文章讲UE4的面向对象编程,本次内容讲解完毕,下一次将会讲解UE4与WEB API的调用,记得点赞收藏转发,谢谢。
番外篇
注释的重要性:很多人都喜欢在写代码或者使用蓝图的时候随心所欲的连,只要实现功能,怎么方便怎么来,如果这样随心所欲没有养成分割成子模块并且进行功能注释的习惯,后期代码维护起来是个很大的问题,所以我这里强调一下制作注释。参考对比图14有注释的情况、图15没有注释的情况
图14 制作每个子模块的注释
图15 作者早期制作车辆不写注释的蓝图
通过上下一比对就发现,书写了注释并且分模块来开发,会让整个蓝图容易差错,起码工整清晰,明白自己要做什么子功能,要做什么其他功能。
具体制作注释的方法为:先选中需要注释的内容和节点,多选的情况下也可以,然后右键——创建注释——增加注释文本——把注释框将功能包裹住。这样就会得到自己想要的注释的模块。
我记得一个段子
某程序员说:我最讨厌两件事,一件事情是让我写代码注释,另一件事情是别人的代码不写注释。
但是为了养成好习惯,要跟进开发进度与功能模块,将蓝图的注释写好,方便后期拓展与维护。