目录
目录
7.修改Crater01、Dunes01、Dunes02的材质
14.修改Rocks01、Rocks02、Rocks03的材质
一、准备工作
创建两个文件夹,分别取名为蓝图和模型(meshes)
将素材包中的模型导入到meshes文件夹内,注意导入的时候要选中合并静态网格体,不然会出现tank散架的情况。
在blueprints里面,创建一个GameModeBase游戏模式基础,取名叫做TankGameMode。
再复制一个第三人称小白人,到blueprints里面粘贴。
在TankGameMode,类里面修改默认pawn类选TanksCharacter。
在项目设置中找到地图和模式,默认模式选择成TankGameMode。
在TanksCharacter,蓝图里面修改自己想要的内容
修改小白人的可视化,点击tank添加网格体
修改胶囊体组件,修改胶囊体的数据
删除画面中的小白人,拖动TanksCharacter到画面中
给坦克一个控制权,搜索poss给玩家控制权,设置玩家0和玩家1
二、制作相机
制作一
制作二
创建一个actor类的蓝图,取名叫做CamerasControl
进入,CamerasControl添加上camera,来填写一下蓝图的内容:
表面方面,我们期望在切换角色时,不是生硬地切换镜头,而是线性的画面转移,所以涉及到新节点set view(中文名:使用混合设置视图目标)
在UE4中,设置混合设置视图目标的节点是用于在游戏中切换摄像机视角的一种方法。以下是对各个参数的解释:
-
目标(Target):这是你想要切换到的新的视图目标,可以是一个角色、一个物体或者一个位置。
-
新视图目标(New View Target):这是你想要设置为当前视图目标的对象。它可以是一个角色、一个物体或者一个位置。(就是让当前的摄像头去新的目标,比如切换后,使用新角色为目标。)
-
混合时间(Blend Time):这是切换到新视图目标时的混合时间,用于平滑过渡。你可以设置一个时间值,以控制从当前视图目标到新视图目标的过渡效果。(当前摄像头去新目标,所需花费的时间。)(混合速度的曲线,比如由快而慢或由慢而快。)
-
混合函数(Blend Func):这是用于控制混合过渡的函数。UE4提供了几种不同的混合函数,如线性、平方根和立方根等。你可以根据需要选择适合的混合函数。(渐变方法(由慢而快,由快而慢,线性,或者其他一些改变视角的方式))
-
混合指数(Blend Exp):这是混合函数的指数值,用于调整混合过渡的曲线形状。较小的指数值会产生更平滑的过渡效果,而较大的指数值会产生更快速的过渡效果。
-
锁定输出(Lock Outgoing):这是一个布尔值,用于控制是否锁定当前视图目标。如果设置为true,那么在切换到新视图目标后,将无法再切换回之前的视图目标。
连接到玩家控制器,注意玩家控制器数值为0/1。
将相机的位置信息复制到新建立的actor上面,将两个位置重合。
三、实时更新相机的位置
添加自定义事件,来实时更新摄像机的位置,
1.相机摇臂的长短
取名为UpdatePos (搜索自定义再取名)
Initial Start Delay是开始延迟0.5秒间隙才开始进入定时器
Time是0.02秒过后进入事件(EVENT)
EVENT:就是每过两秒要进入的事件,当前事件为UpdatePos
Looping:就是设置循环,每0.02秒过后进行一次进入事件。(不止一次)
先建立一个相机的位置
再创建一个目标位置
通过数组设置当前玩家的位置
接着来判断一下数组的长度,长度不等于0,则表示不是空值
不是空值就可以进行赋值
获取player0的两个位置,get玩家1玩家2
让这两个向量相减,获取到这两个向量的长度
算出来的长度也可能是负数,搜索abs,让他变成正数,成为绝对值
由于地图很大所以地图里面的数据也会很大,所以这个时候要取他的平方根,开完方得到的数据就是他们的距离
需要乘一个长度,为了给摇臂动态数值,乘一个小数调节长度。*(float×float),并且提升为一个变量
2. 开始使用摇臂
设置目标臂长度和数据相连接
当两个太近或是太远 可能返回值是10或者20,那么摇臂摄像机和坦克就叠在一起了,所以现在还要调整一下返回值的长度,将数值限定在一个范围内,有最小值,有最大值
数值给到500最小,5000最大
那么第一步的摇臂长度已经做完了
再来调整相机拍照位置,在两个坦克之间,给newpos赋值,相加后在除以2
拉动到set右侧
可以直接连接赋值,将他们设置为平滑移动
V插值是一种用于平滑插值两个值之间的节点
Current:表示当前的值或状态。
Target:表示目标值或目标状态。
Delta Time:表示两次更新之间的时间差。在游戏中,每帧都会有一个时间间隔,Delta Time就是这个时间间隔的值。
Interp Speed:表示插值的速度或者过渡的速度。它决定了从当前值到目标值过渡的速度有多快。
V插值节点可以用于各种情况,比如平滑移动物体、平滑过渡动画等。它通过在每一帧更新当前值,使其逐渐接近目标值,从而实现平滑过渡效果。
将oldpos设置一下,oldpos=newpos
调整一下间隔碰撞
设置摄像机碰撞
四、调整地形
拖动地形,terrain
选择这个当作地面地图,修改他的参数
调整光照效果(可移动)
1.修改悬崖的颜色
颜色9F6D3E
2.修改地面的颜色
颜色FFD954FF
3.修改Building01的材质
颜色:A99E88
颜色:373C51FF
颜色:6F6767FF
4.修改Building02的材质
5.修改Green的材质
颜色:63962AFF
6.修改Column的材质
Column01的材质
Column02的材质
7.修改Crater01、Dunes01、Dunes02的材质
8.修改Helipad的材质
修改OilDrums的材质
9.修改OilStorage的材质
10.修改PalmTree的材质
11.修改PumpJack的材质
12.修改Radar的材质
13.修改Refinery的材质
14.修改Rocks01、Rocks02、Rocks03的材质
15.修改Ruins01的材质
五、调整光线
把强度拉大,画面中有种朦胧的效果
打开曝光视角,为了模拟人眼的亮暗强度(特别亮的环境到特别暗的环境,眼部会适应几秒),可以切换太阳和暗处查看一下区别
可以选择直方图,也可以选择柱状图,曝光补偿是越小越亮,越大越暗
添加暗角
添加环境光遮蔽(表示物体和物体之间的遮挡)
六、动态修改坦克颜色
为了区分玩家0和1,将内容放置到gamemode里面
新建一个变量,叫做playercolorer
思路:首先需要获取到数组里面的两个player(1),在获取两个坦克(2),来查看坦克材质会发现我们需要获取到0号(3),再访问0号材质颜色的参数(4),将材质的名字修改成colors(5)。
(1)
(2)
(3)
(4)
1.先自定义一个事件,将数组里面的两个player获取到(直接复制之前摄像机的内容)
当数组不为空的时候,设置一个循环,获取到动态材质实例,将目标连接上去。(获取的是0号参数)
接着我们获取到了动态材质,设置向量参数值,将我们预设好的参数值,名字对应上colors
那么我们就需要做一下预设的参数值,对应上参数值,和index连接起来
获取到玩家的元素0
将index的数值对应上playercolors的get
最后设置一下材质,return value连接上material
那么在事件最开始的时候,我们需要运行这个自定义事件
蓝图结果:
运行结果:
七、子弹生成
1.修改按键截图
2.添加子弹
新建蓝图取名叫做Shell
将子弹的x轴旋转90度(-90°)
添加发射物移动组件后,子弹就可以运动起来了,并且具有重力与初速度
重力越重,飞的越近。重力越轻,飞的越远
子弹(Shell)左侧组件:
制作坦克发射子弹的蓝图:
(英文翻译)lauch:发射
指定到对应的actor
3.修改子弹发射频率
冷却时间判定是否可以发射
是否进行限定发射
用分支来判断一下能否发射,发射完了就代表销毁掉
再判断是否限制子弹的冷却,如果不限制走F,就可以一直发射
如果限制走T
再判断一次,如果不被激活走F,就可以进行下一步射击
如果被激活走T
记得把限制打勾
八、血条
1.添加血条
ui内的内容,选择一个血条
将文件迁移到另外的工程里面
把文件放在content里面
在我们的资源浏览器内会发现多了一个文件夹
在文件夹里面新建一个ui文件夹,再创建一个控件蓝图
打开控件蓝图,创建一张图片,将素材导入
动态的修改血量材质(范围是0—1,0是没血,1是满血)
先修改成1的参数
搜索debug查看,修改血量自动的选项
修改锚点为居中
将画面居中
把UI添加到坦克身上,在坦克的蓝图内添加组件
旋转一下角度和调整位置
\
运行画面:
2.更新血条状态
做一下伤害处理,新建两个变量,一个当前的hp,一个max的hp
来完成一下伤害处理,按下p键调用事件开始运行时,给当前数值赋血量,最大值给到300
在UI的tankbar里面写一串蓝图,当玩家受伤的时候就可以找到HPBar身上的函数
首先获取image0,在获取材质,设置参数值,将血量值和最大血量值传给他
给到两个数值,类型为float,将两个数值相除
接着在初始化的时候调用
3.子弹血量
调整碰撞检测,把生成重叠事件开启(开启后事件开始重叠时才有用)
判断当前击中游戏物体需要是tank,击中后打印
会发现他会打印两个,是和自身碰撞后又和对面的坦克碰撞,解决方式
1.把自己的碰撞改小
2.修改子弹owner为自己()
这时候就可以回到shell蓝图里面呼出get owner
运行的时候会发现碰撞会多次掉血,这时候调整碰撞
把子弹碰撞都关闭
先把碰撞全部关闭
(1)
(2)
(3)
九、切换玩家
将切换节点取消调用,因为我们有两个玩家,玩家一调用wasd,玩家二调用上下左右。
所以不可以写在一个蓝图里面所以写一个自定义事件,在蓝图里面调用
在蓝图里面看输入,wasd调用moveri,
需要全局引用的调用(在里面可以对于任何一个东西调用),在关卡蓝图里面填写
调用到引用后就可以获取游戏物体上的东西,或者是变量。
打开关卡蓝图
先调用两个坦克
1.添加按键输入
搜索键盘+空格+字母
会发现按一下键盘只移动一次,想要一直调用,就用事件tick
在赋值之前可以先来判断是否可以赋值,如果小于等于-5那么就不赋值,如果大于-5那么就赋值
给到ri和for变量数值为0
会发现现在再进行操作,坦克可以运动了,但是停不下来了,那么就要来写一下归零的操作
2.添加玩家
再来写一下第二个坦克,创建玩家,(-1代表下一个可用的玩家id)
十、加强子弹的制作
完善玩家二的子弹生成,现在只有一个玩家可以发射子弹,可以做成案件调用
制作成自定义事件,做一下按下去就生成的相应操作。
1.导入箭头
创建一个spite
回到坦克中制作
修改尺寸和位置
修改图片中心点
再场景中看一看效果
最开始的时候箭头不显示,所以设置为不可见
修改封装成自定义事件,之后再调用
再调用
调整箭头的碰撞,取消重叠事件(没有碰撞就不会参加事件的碰撞相应)
那么按下按键就需要添加可视性
根据剩余时间的多少来判断发射的长度
回到蓝图里面调用一下
超出时间要限定时间,大于零就发射子弹(大于零没有到时间不能生成子弹要手动的调用)
2.填写箭头的3d缩放
OnUpdatingShootArrow
3.修改子弹的重力
距离越远时间越小
长按数值为0
如果数值为0,那么我们需要判断一下,如果等于0,就手动赋值给0.1(蓄满力)
十一、制作回合
制作画面:
制作思路:通过玩游戏的ui来查看有几轮结束游戏,并且赢了的玩家的游戏颜色显示在ui字体上
1.创建蓝图存放游戏数据
取名为tankGameState
调整一下项目设置的游戏状态类
打开tankgamestate,开始创建变量
(1).GameRound游戏关卡数字为5,赋值为5
(2).CurrentRound先进行赋值为1
(3).PlayerWinTimes创建玩家1和玩家2
(4).winnerplayerid(判断是玩家1还是玩家2赢了)
回到tankcharacter继续调用
2.辨认哪一个玩家死亡
然后创建自定义事件在设置血量状态
用当前的血量和0来比较,如果小于或者等于0,那么玩家就死掉
根据判断游戏玩家的死亡动态的修改tankgamestate里面的游戏数值
那么就在判断之后,看一下是哪一个玩家死亡,所以需要获取到玩家的ID
如果玩家0死亡,则player1获胜。如果玩家1死亡,则player0获胜。
先强转成当前的tank,来设置现在的获胜者(winner)
获取到winner的id
如果玩家0死亡,则player1获胜。如果玩家1死亡,则player0获胜。
再继续设置每个玩家的winner times
注意逻辑:要注意一下输入的和连接的数字是相反的,谁调用这个事件就说明谁的坦克死了,坦克死了就说明对方赢了,首先获取到死亡的坦克id(如果玩家0死亡,则player1获胜。)先强转成当前的tank,来设置现在的获胜者的id,再让winner times,赢的次数加1。
将赢的结果打印出来,使用append(附加)节点
append节点的含义就是将多个字符串的内容相连
(调用的endround的部分需要把十一节第4部分写完才能调用)
记得把打印字符串的内容不要输出在左上角屏幕
全图:
3.创建获胜的UI
创建控件,导入字体
回到tankgamemode里面修改颜色的透明度,a修改为1
在ui的字体右侧,创建绑定,
获取颜色和不透明度0,回到事件图表,将这两个tankgamemode和tankgamestate提升为变量
回到获取颜色和不透明度0事件获取到对应的颜色
继续创建绑定玩家0
再创建玩家1的颜色
再绑定输出玩家0数值的参数
(注意冒号:写出中文的,间隔比较大)
以及玩家1数值的参数
(注意冒号:写出中文的,间隔比较大)
再绑定标题赢的玩家的名字和颜色
gettext2
4.生成UI显示在屏幕上
简易版写在character里面、复杂版写在gamemode里面
十二、(选做)简单回合重置版
1.重置关卡部分
(1).暂停游戏并上传数据
游戏结束后,将游戏暂停,显示鼠标,设置为UI可输入模式,接着上传游戏数据到存档(保存游戏函数在游戏状态里单独创建)创建关卡重置按键
(2).创建关卡重置的UI
游戏暂停后会弹出UI框,设置一个按钮让关卡重置
创建完后来到事件图表,左侧变量选中按钮,下方事件选中点击时,执行条件为点击按钮即可,接着清除UI,将游戏暂停取消,隐藏鼠标光标,设置为游戏输入模式,并重新打开关卡即可
(3).创建游戏存档
创建完存档后点击进去,创建一个整数数组变量,用于保存记录玩家获胜数据
在gamestate里创建一个savegames的函数,上述当游戏结束时调用这个函数,先创建一个游戏存档对象,然后提升为变量,拖出存档数据win times和当前游戏数据player win times,将他们的元素分别拖出进行一个相加,意义在于将当前游戏输赢数据player win times覆盖存档数据win times里,也就是将当前游戏数据保存到存档,接着设置阵列元素
接着把游戏数据保存到插槽里,可以理解为存档1(这个插槽也要提升为变量并且要命名)
(随意给一个数值)
在gamestate里设置游戏存档,判断是否有存档,有存档就从插槽加载当前存档,将类型转换为刚才创建的游戏存档类型
接着拖出在存档里创建的数据节点win times,以及当前游戏数据player win times,再把刚才保存的游戏数据重新赋值给当前的游戏数据,同样设置一些阵列元素,以实现类似于游戏读档的功能,这样游戏数据在清空之前就会被永久保存,不受启动/关闭引擎的影响
2.运行画面
1.坦克操控
2.坦克近距离发射子弹
3.坦克远距离发射子弹
4.互相打击扣血
5.扣光血出现UI
6.点击reset重开一局
7.出现第二把第三把的局数
十三、(选做)复杂五局回合版(接十一后)
1.生成UI让玩家不能控制
写一个遍历让所有的玩家的控制器取消,这样游戏一旦结束就没有人能够控制游戏了
那么就来写一下控制,首先新建一个布尔变量Can Controll,默认是不可以控制的,当游戏开始round1之后才可以控制坦克。
将所有的控制之前添加判断能否控制
把mouse input和gamepad input删除(这两块是UE自带没有用)
回到tankgamemode添加一个自定义事件来判断游戏开始或结束
首先先来判断一下
1.当前游戏局数(CurrentRound)是否大于5局(Game Round数值为5)
2.玩家获胜局数(PlayerWinTimes)是否大于5局(Game Round数值为5)
如果不大于5则重新继续游戏,大于5则结束游戏(记得添加自定义)
节点解释:OR运算(逻辑或)
-
符号:通常表示为 ∨ 或者 |。
-
定义:如果至少有一个输入为真(1),OR运算的结果就为真(1)。只有当所有输入都为假(0)时,结果才为假(0)。
-
真值表:
A (输入) B (输入) A OR B (输出) 0 0 0 0 1 1 1 0 1 1 1 1
2.重新开始一把新游戏
当前游戏对局结束后,想要重新开始新的游戏,那么就需要把UI的控件先去除,添加第二关的控件,再将第二局的
那么就需要添加新的UI(第二关)
创建UI修改字体
那么每一句的局数就会显示在UI上面
添加新的UI到播放器,延迟两秒后,开始将所有的控制给上,将start UI去除
3.结束游戏
十四、添加音乐
将背景音乐移动到画面中,运行的时候就自带背景音乐
将音乐选择循环模式
在坦克中也选择音乐,在按下上下左右的时候播放drving的音乐
添加爆炸的时候的声效
十五、添加坦克击毁后的效果
添加静态网格体,添加坦克击毁后的效果
会多次射击
解决bug:1.将碰撞去除
解决2;
十六、添加坦克特效
将坦克的特效进行添加,将粒子特效放在文件的content当中
十七、添加摄像头抖动
十七、打包