unity3D技术分享Unity基础入门分享征服Unity3d

Unity官方教程 2D Roguelike(5):敌人移动

2019-08-23  本文已影响0人  小巷里有只猫
2D Roguelike 最终效果

前言

Unity官方教程 2D Roguelike(4):角色移动中,我们完成了游戏最主要的功能——角色移动相关逻辑,接下来只要完成怪物的移动,整个游戏的底层架构就差不多完整了,除了UI和音乐音效等。这一节我们主要完成以下内容:

本节你将学会什么?

一、编辑Enemy Script

2D Roguelike是个回合制游戏,我动敌静,敌动我静。接下来创建一个Script,命名为Enemy,双击打开编辑怪物敌动代码吧!

第1步:MoveEnemy()

MoveEnemy()

代码简读:

游戏管理器GameController会调用MoveEnemy()方法进行指挥怪物队列移动,因此关键词为public。

Mathf.Abs指的是绝对值。float.Epsilon是最小浮点值,接近0。
条件?结果A:结果B,是三元运算符的表达式,条件结果为true则是表达式结果是A,否则是B。

从上面的代码解析可以看出,MoveEnemy()干的活就是根据Player坐标确定怪物移动方向,然后调用AttempMove<Player>()进行真正移动。

第2步:AttempMove<T>()

AttempMove<T>()

代码简读:

从上面的代码解析可以看出,AttempMove<T>()干的活就是接收到MoveEnemy()的信息通知往哪边移动的时候,判断下这回合要不要跳过,然后再进行移动。
OK,怪物开始移动了!哒哒哒,哒哒哒,诶?遇见Player了!好家伙,要打的就是你!

第3步:OnCantMove<T>()

OnCantMove<T>()

代码简读:

二、编辑GameController

在上面的Enemy Script里,我们实现了怪物基本移动逻辑(根据Player坐标确定方向进行移动,与Player碰撞的时候调用LoseFood()方法实现攻击Player效果)。作为游戏管理器的GameController,则负责调控全局,指挥多个怪物在一定的条件下依次调用Enemy Script进行移动。

第1步:增加怪物队列集合

打开GameController,增加以下代码。

enemies

代码简读:

这句代码的意思是调用GameController的公有方法AddEnemyToList(),把自己(当前实例)当成参数传入进去,也就是把当前怪物加进集合enemies。正因为需要在这里进行调用,所以AddEnemyToList()方法的关键词是public哦~

第2步:指挥怪物们依次移动

关卡内的怪物都被添加进集合enemies内了,接下来就是在恰当的时机指挥这些怪物一个个移动啦!

指挥移动

代码简读:

协程是分步骤执行代码的程序,遇到条件(yield return语句)会挂起暂停退出,直到条件满足才会被唤醒继续执行后面的代码。

第3步:填坑-playerTurn开关

移动逻辑章节的第三节内的第3步,当时为了修正按一次方向键而Player移动了多次的问题,我们临时增加了一些代码。现在已完成怪物移动代码,可以正常地进行人物怪物交换来回移动,因此我们需要把之前临时增加的三句代码删除。

Player Script的Update() MovingObject Script

然后我们在Player Script的AttempMove()方法内对playerTurn进行赋值改动。

playerTurn改成false
也就是说,人物开始移动之后立刻把playerTurn赋值为false,这样游戏管理器的Update()判断playerTurn和enemyMoving都是false的时候,它开始指挥怪物们进行移动。怪物移动完毕之后,把playerTurn赋值为true,Player的Update()即可执行后续代码让Player开始第二次移动。
当然,我们也不要忘了即使轮到怪物回合了,它也有选择不走的权利!太懒惰了,怪物利用skipMove这个开关,成功实现人物走两次,它才动一次。(和我一样懒( >﹏<。)~)

第4步:执行移动

保存脚本,切回到Unity编辑器。打开Prefabs文件夹,同时选中Enemy1和Enemy2预制件,再点击菜单栏的Component-Scripts-Enemy,把Enemy脚本挂载到这两个预制件上。

挂载Enemy脚本

在右侧Inspector内的Enemy组件里,Blocking Layer选择BlockingLayer层。

设置Layer层

单独选择Enemy1预制件,把它的Player Damage设置为10,而Enemy2的为20。(这里可以自由发挥设置伤害为多少,但是注意不要过高一招就把Player秒了……)

设置Player Damage数值

最后一步,开测!

胜利就在前方,大家冲鸭!

运行游戏,我们按键盘的方向键让小人走起来。


可以看到游戏正常耍起了:

但其实我们会发现这个游戏的怪物移动逻辑会有一个缺点:怪物如果被障碍墙挡住了,会一直卡着不动,直到小人移动变换左右或者上下,它才有可能再动起来。这个是由于Enemy脚本的MoveEnemy()方法里面获取移动方向的设定上不够灵活。感兴趣的童鞋可以想想如何优化这个怪物AI~

虽然看起来除了音乐和UI,其他逻辑都做完了。但是细心的小强同学却发现了:“老师,怪物攻击Player的时候没有动作展示!”

真聪明!

那接下来我们就把动画补上吧!

三、实现怪物动画添加

怪物动画的转换只有一种情况:怪物遇到Player并且进行攻击,这时候怪物的动画从idle切换到attack,并且在attack动画结束之后切换回idle。
其实在上一节我们已经介绍过角色动画的转换是如何设置的,而怪物的动画设置上基本上是一致的,所以很多细节和这样设置的原因是什么我就不再赘述了。

  1. 双击Enemy1动画控制机打开Animator面板,在Parameters里增加Trigger名为enemyAttack
动画触发器
  1. 通过右键的Make Transition在Enemy1Idle和Enemy1Attack之间创建连接。
动画切换关联
  1. 选中高亮从Enemy1Idle出发到Enemy1Attack的线,对动画转换进行设置。
Idle到Attack
  1. 选中高亮从Enemy1IAttack出发到Enemy1Idle的线,对动画转换进行设置。
Attack结束回到Idle

如此就完成了Enemy1Idle和Enemy1IAttack之间的互相转换的设置。由于Enemy2控制器是重写控制器,自动继承Enemy1的设置,所以不需要再去编辑Enemy2的两种动画状态之间的切换了。
怪物动画的切换设置完毕,我们需要在Enemy脚本里添加触发动画的代码。

编写Enemy动画触发代码

代码简析:

可以看到怪物攻击小人的时候有对应的攻击动画出来啦!
ヾ(゚∀゚ゞ)快接近尾声了。接下来只剩下音乐音效、UI、切换关卡处理等部分了!等我一篇搞定~

上一章传送门:角色移动
下一章传送门:音乐音效、UI

上一篇 下一篇

猜你喜欢

热点阅读