siki学院制作塔防游戏教程

 1.创建地图

       塔防游戏的第一步便是创建地图,利用3D Object里的plane先创建一个平面,最好把它的坐标回归初始化(50*50大小),在这个步骤之后,我们需要给plane添加颜色,也就是利用Material材质球进行修改颜色等外观性质(最好直接建立一个有关材质球的文件夹将其放入),所以建立一个材质球名为Mat_plane,选择一个合适的颜色,拖入plane对象中。

       之后利用3D Object里的Cube创建地面(4*4大小),让每个地板之间有一米的间隔,注意要把Cube里的collider删除,因为不需要做碰撞检测,并把它制作成一个预制件,方便统一修改。最好建立一个文件夹统一管理Cube。

       然后开始复制粘贴Cube,按住Ctrl键进行步移,如果需要改变步移的大小如上图二。最后效果呈现出一个15*15大小的地图。

       选择出怪物行走线路(按住shift多选),删除之后添加上新的方块(材质球和上面的方法一样),行走路线的方块最好也作为一个预制体,因为位置不太好确定,所以最好是复制MapCube的来成为路线,但是又是属于MapCube的预制体,所以需要取消预制体下图三。完成后如图四

建立起始点和终点,建立方块,建立材质球,选择颜色。

2.视野的设置 

      先将摄像机调试到合适的位置 

      创建一个脚本用于摄像头的移动和放大缩小,该脚本放到Main Camera中

3.敌人的生成和移动

     设置路径点Wayponints,在拐角处设置Waypoint,然后在Waypoints上挂脚本,因为方便管理。

    在敌人物体上挂脚本如下

      需要注意的是数组的索引是从上到下 也就是按照这样的顺序

4.创建敌人孵化器 

      在继续创建不一样的敌人类型之后,创建一个脚本,用于控制总波数,出怪得间隔,每波怪的数量。该脚本不作为如何游戏物体的组件,所以需要把MonoBehaviour删除,原因还是因为要在前面加一行[System.Serializable] 表示可以被序列化 ,并且把MonoBehaviour删掉,否则在Unity中显示的就会是一个组件而不是每个数值,如下图二。

     之后创建一个脚本Enempy Spawner 如上图二的功能所示

但是现在有一个问题就是还没到达终点或者场上还有上一波存在时,下一波已经出来了,所以对代码进行改进设置了一个变量,判断此时敌人的数量。在敌人脚本中添加销毁的情况分为到达终点和死亡。如下图二

5.创建炮塔

1.设计炮塔以及升级后炮塔的颜色的颜色 (素材放在尾部)

       在预制件文件夹归类出三种炮塔,分别设计,需要注意的是Missile炮塔的炮弹得作为一个单独的预制件。

2.选择炮塔UI

      创建ToggleUI,将背景板更换为对应炮塔,值得注意的点是如果想完成单选需要借助ToggleGroup组件,建立一个游戏物体,里面放入ToggleGroup组件,如下图二,再在每个炮塔UI的Group中放入这个组件。

3.炮塔的实现

       首先写出一个炮塔数据类,里面存放着炮塔数据。还是一样的操作,他只存放数据所以要把MonoBehaviour删除,并添加序列化。

    在创建一个建造管理脚本 放在GameManger里,在里面写入三个炮塔数据类对象,分别对应三种炮塔,并且因为需要使用按钮按键,来监听选择了哪个炮塔,所以需要三个选择炮塔的方法。

    之后在Unity 中拖入相对应的预制体。

   接下来就是拖拽按钮选择方法。

4.鼠标选择了哪个Cube 

 原理是鼠标左键发出射线,识别是否碰到了Cube,然后还得判断Cube上面的是否不存在炮塔,如果存在是升级选项,不存在的话就是建造选项。建立一个MapCube脚本放在MapCube上(利用预制体放)。out hit后面还有一个1000表示射线的距离。

5.创建炮塔升级的UI

创建UI画布

将其改为world space

添加按钮 可能会和之前的画布重合,所以需要拖走。

记得把Button下的Image取消掉,不需要背景颜色。

之后先拖入一个炮塔,将UI拖入炮塔里。调整位置与大小。

将其修改为漫画模式  因为它会自动创建好Animator而HighlightedTrigger的意思就是鼠标放在按钮上显示是什么动画

添加关键帧使其展现出自己想要的结果

接下来就得对升级按钮的显示和隐藏写方法,我写在了BuildManger的脚本里

将点击事件分别拖入升级和拆除里(以下只演示了升级的)

接下来就是继续编写脚本告诉其如果上面有的话才会显示 这两个按钮

在MapCube脚本中添加  判断是否已经是升级的炮塔 记得加保险在Start的方法中再让他为false

这个时候你会发现它与上面脚本中的默认是False一样,也就是说BuildManger的升级处理的脚本可以这么写,但是又发现了一个问题,字体出现在了地板里,所以如下图二。多添加一句把它上移的执行语句,使字体调整到一个合适的位置。

完了之后就可以点击,但是你会发现如果你误触了某个已经有炮塔的地方,那么跑出来之后就没办法关闭,所以接下来我们要解决这个问题。

在定义一个变量selectedTurretGo用来判断是否点击的是同一个炮塔,如果点击的是同一个就关闭UI界面,否则就是第一次点击就可以显现。(下面也是在BuildManger里的执行语句)

接下来,我们可以考虑给UI界面隐藏和显示时添加一个动画。利用这个选项实现一个缩放的功能show。那么关闭时,当然也要有一个缩放的功能hide。

show的loop循环需要取消勾选,且只有show进入hide无hide进入show

箭头的下图记得取消勾选

创建一个Trigger的变量,用来控制是否进入hide

而后在BuildManger脚本中创建一个动画管理器,在Start中获取

关闭时设置一下先让动画播放完了再关闭,因为改成了这个协程,所以方法的调用方式也得改变。

但是又有一个问题,就是如果只是单纯的这样,那么当一个炮塔上已经如此显示UI界面,当这时候点击下一个炮塔,并不会播放Show的动画,所以要对其改进一下。先禁用再开启就会显示动画。

但是我们还没处理按钮的点击事件,所以接下来来设计呢。

首先设计升级,因为建造放在了MapCube的脚本中,所以我觉得升级和拆除也得放入,但是我们知道我们刚开始传递监听的只是TurrentDate里的炮台,也就是他不会知道自己升级后是什么样的炮塔。所以我们需要修改一下

先把后面那段删除,这样子传递过去的就是一整个Data了,也包括了他升级的。

蓝线部分改成现在得蓝线部分,因为本来是GameObject但是现在是一个数据类,不是游戏对象。

修改成蓝线部分,道理类似。这里得放游戏对象。

创建一个变量得到传进来的

并且建立好拆除和升级的方法,后面会使用。

但是我们发现我们是通过MapCube进行升级的,我们又得知道我们点击的是哪个MapCube,所以把GameObject的selectTurrentGo改成MapCube的selectMapCube ,并且把下面的判断条件也改掉。(都是我鼠标选中的地方)

这样子就可以直接调用这个方法了。(因为升级完了要关闭所以继续调用协程方法)

在拆除和升级里添加代码

给他们也加上特效,就是把建造的特效复制过去。

6.炮塔升级的预制件制作

首先我们得先把一些刚开始用于调试所以设置为public的改成private,不让它显示在Unity中,比如下图

然后按照相同的方法建造预制件,该拖入的拖入,改Head的Head(记得Y轴旋转270度)。

然后将MissileTurrent的炮塔如法炮制,剩下的一个作为激光炮塔的实现。

建造激光炮塔时因为是发射激光所以我们需要在Turrent的脚本中添加一个bool类型,来判断是发射激光还是发射子弹。并且需要分类一下子弹和其激光的方法利用ifelse。

之后建造一个新的游戏物体,为他添加LineRenderer脚本。并为其添加材质,设置宽度利用右边的红线,End Cap Vertices设置一下是为了让它末尾和起点出现圆形。

如果发现UserLaser为true并且存在敌人,那么就会先把激光打开,然后为了保险起见如果数组里第一个敌人为空,那么将其刷新集合,接下来,就是正常激光头部和尾部应该出现的位置,如果没有敌人了那么就把激光关闭。

那么接下来就要为激光添加伤害、

之后便是制作特效,新建一个游戏物体,添加Effect,添加一个材质球,并且改变属性(可以作为参考)记得把Gravity Modifier改1,受重力影响。

设置大小随时间变化。

发射点改小

接下来就是设置出现的位置,当不需要激光的时候取消使用,当需要时Setactive(true),之后就是让它面向炮塔,但是高度得在敌人身上,否则高度将会在地板的高度。

6.金钱管理

在BuildManger中添加金钱减少的方法

在建造条件都满足的地方调用

那么当然也要有没钱的提示

       在界面选择好Money后点击Window点击Animation之后便可创建动画(建议是也专门用一个文件夹存放动画),最主要的是先滑动到自己想要的时间结点,选择颜色,然后再添加关键帧。 因为主要是修改颜色所以点击add里面有个color。

         选择它的动画管理器,之后会发现自己创建的动画和他是直接相连,是不可以的,需要重新创建一个空动画作为默认。创建一个Trigger类型的变量,用来判断是否播放动画,并把他放在默认空动画指向Filker的线条里。而且需要把Fileker的Loop Time取消勾选,防止他循环播放。

在BuildManger脚本中写一个动画管理器变量

钱不够的话就把Tigger类型的Filker设置为真

7.建造的泥土特效 

新建一个游戏物体,里面按照如下方法创建粒子特效(可以放一个炮塔在旁边看看) 

记得说把粒子的坐标改为(0,0,0),把他的角度改为向上(未显示在下面)。

像素风格(下图)。

添加材质球,为接近泥土的颜色(未显示)。

发散一次就好(下图)。

初始速度(下图)。

发散形状(下图)。

0.3秒内完成(下图)。

生命周期(下图)。

size over time(下图)。让粒子有逐渐减小的感觉。

loop取消勾选 播放一次就好了

脚本如下,记得将特效拖拽到MapCube脚本中

8.检测敌人与攻击敌人

1.检测敌人

     在炮塔预制件中,添加collider和rigibody;rigibody中的重力取消,collider中的Is trigger选上。

为敌人添加标签 注意坐标Tag那里

在Turrent脚本中写入碰撞检测的方法,分为离开和进入,当未离开或未被消灭时只攻击一个

将炮塔和怪物设置在两个层级,炮塔只允许和怪物发射碰撞检测

2.子弹发射的方式 

在创建一个游戏物体 用来定位子弹出来的位置

 在Turrent脚本中添加代码,Gameobject里拖入子弹,子弹也是自己创建的游戏物体,最好是球形,把子弹也作为预制件,顺便把之前的子弹也拖入这里。

之后要设计子弹跟随敌人

子弹碰到敌人的碰撞检测也是老样子给子弹添加刚体和检测器记得把Is Trigger点上(防止改变敌人的位置),然后重力也要忽视掉。

3.添加爆炸特效

仍然是向上 添加材质球(未显示)。

3d像素风格(下图)。

修改和上面的建造的泥土特效差不多 loop也要记得取消勾选(下图错了忘记取消了)

在Bullet脚本中添加碰撞的代码

记得把Bullet也设置为Turrent层否则特效不会触发,因为Enempy只和Turrent层做了碰撞检测。

中途BUG的处理

写到这里后意外发现了几个Bug。

1.如果正好子弹追踪的敌人到达终点时,子弹还没追上它,子弹就会停留在半空中。

解决办法就是当敌人为空时就销毁,所以再在Bullet中写一个方法便可。

 这时又发现了另外一个Bug,就是观察最底下-= 但是你会发现当游戏开始后,你放了炮塔之后因为是在Update中的方法体,所以他就会一直自增,如果你用-=那么当敌人到达之后,时间早就是不止一秒了,所以最好的办法就是让它直接等于0。(下图二为改进)

2.可能敌人在攻击范围内就销毁了,但是还在集合里,就会出现空指针异常。

4.敌人的销毁爆炸

把子弹的粒子特效复制一份,Collision中加上这个也就是碰到物体,粒子速度减少。(需要注意的是材质并不可以直接拖拽而是在下图一中的Material)

顺便把重力设置为一

在敌人脚本中添加方法和变量

其他的就是赋值粒子,然后拖入就好了。

5.炮筒指向要攻击的敌人

 如果只是单纯得将脚本方法添加入炮塔,但是炮筒是围绕着自身的中心点旋转,就会出现以下。

所以得新建一个GameObject 将他们的z轴保持一致(蓝色是z轴)

之后将head拖入到这个游戏物体下方,可能需要解除预制体关系

脚本如下(添加在Turrent的脚本中)

6.添加敌人血条显示

新建一个画布之后建立slider 删除掉下图篮圈

将画布的Render Model改成world space 就是把UI当成一个三维物体

因为不需要交互 所以slider的Interactable取消勾选

之后将其拖入 拖入后先将位置改为(1,1,1)然后在修改合适的大小,最后再微调一下位置。

添加Enempy脚本的方法 然后把敌人爆炸的特效设置为公共的,之后将slider拖入就好了。

9.设置鼠标移动到MapCube上时,地板变红。

添加脚本如下。 

 

记得去图层是否碰撞的面板把Queries Trigger取消掉

并且需要一个材质球 放入Cube里,因为他是默认的颜色,没有修改的选项。

10.升级的金钱消耗

添加脚本

11.设计游戏结束的UI

在画布下添加一个游戏物体,里面放入一张Image,并添加关键帧,实现慢慢出现背景。记得把接下来动画操作取消循环。记得把游戏物体的大小调成和画布一样大,右边蓝色的那个图标。

继续为Retry和Menu添加关键帧

控制结束页面的显示

失败页面:失败的条件是有敌人到达终点。

所以我们创建一个新的脚本,里面包含失败和成功的页面。

因为刚开始得让他们不显示所以在Start里false掉,因为控制波数,和每波间隔是在EnempySpawner中,所以在这里面添加一个停止生成的方法Stop,值得注意的是这里关闭是这用,所以开启时不可以方法名+括号,也得改成双引号。

到达终点在敌人自己身上的脚本,所以直接在这里添加上GameManger脚本里的失败方法。因为是单例模式,可以直接调用。

添加胜利页面

条件:当不再有敌人之后便胜利 

直接再敌人孵化器这里遍历完之后显示出这个菜单。

点击按钮的界面 记得拖入

写入代码 一个是重新加载当前场景一个是加载菜单场景。

12.菜单场景的建立

首先得创建一个新的场景,在新的场景里建立一个500*500*500大小的plane(坐标重置),之后把Stand开头的炮塔拖入这个场景,FirePosition和head都可以删除了,留下炮塔自身就好。

在创建一个游戏物体坐标重置后把炮塔拖入。

建立一个画布,记得改为WorldSpace。

画布调成合适大小

不需要背景Image移除

把他拖入到炮塔下,作为炮塔的子物体,然后调整相机调整位置,达到下图效果

添加动画

把升级按钮的特效添加进去,添加一个组件Animator

给包含炮塔和画布的游戏物体添加一个动画,实现炮塔旋转

添加按钮点击脚本,蓝色鼠标选中的意思是在编译器模式下也可以退出。

然后拖入场景(记得按上面的顺序) 游玩界面是第二个拖。

然后叉掉这个界面便可。

这个系列就到此结束了,细节大差不差,可能有些Bug我修改的时候忘记加进去了,下次记得改Bug时的过程也加进去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值