逻辑帧设定

我们在EnemyCreatorMgr中使用IUpdate.UpdateFun()来选择合适的EnemyCreator并生成敌机,在EnemyCreator中使用IUpdate.UpdateFun()来确定当前的队列生成的最后一个飞机已经完全进入摄像机视野,这两个敌方并不需要每帧都更新。

我们在IUpdate接口中声明UpdateTime属性,每一个实现这个接口的对象都需要指定自己过多少帧更新一次,然后再声明Times属性,每一个实现这个接口的对象都需要单独记录目前已经过了多少帧。

我们修改LifeCycleAddConfig.LifeCycleFuncs,在其中添加判断逻辑。

修改完成之后,普通的IUpdate不需要对这两个属性赋值,在需要赋值的类里,直接赋值UpdateTime即可,Times属性永远不需要被赋值。

敌机飞出屏幕后回收

Enemy中添加JudgeBeyondBorder方法,并且添加LimitUpdate方法,敌机的回收也不需要每帧都判断。

生成星星

敌机被毁后生成星星。

添加星星Prefab,记得加上CircleCollider2D Trigger和Path。由于星星图片在UI中也会被使用,所以我们直接把星星prefab的缩放改了,不改星星图片的pixel per unit。

EnemyBehaviour.Dead中将星星的prefab实例化出来,我们的星星也通过对象池管理。星星的碰撞消息不需要类似飞机的那样进行处理,所以我们新建一个ItemCollider2DMsgComponent,这个Component专门用来让星星钻石等漂浮的奖励物品挂载,所以里面的逻辑比较简单,它只能和Tag为Plane的物体碰撞,里面还声明了一个委托,不同的奖励物品监听这个委托即可。

Collider2DMsgComponent修改为PlaneCollider2DMsgComponent

星星的表现逻辑,通过View文件夹下的StartView脚本来控制,星星变化的动画,通过StarAni脚本来控制

修改EnemyBehaviour的Bug

当一个敌机被Player的多个子弹打中时,在那一帧会多次调用EnemyBehaviour.Injure方法,敌机的生命值归零时,再次碰撞的子弹应该不会调用其他的方法了,这里需要修改。

吃星星UI动画

飞机吃到星星后,奖励会飞到对应的UI界面。

UIMgr中添加获取某个View的Transform的接口。使用Dotween让星星飞到UI界面上即可。

精英敌人生成

LevelData中添加NormalSpawnNumForSpawnElites,生成一定数量普通敌人后生成精英敌人。注意还要在EnemyLevelConfig.json中添加好同名配置数据。

EnemyCreator中开放GetSpawnNum方法,获取当前已经生成的敌机数量。在EnemyCreatorMgr中添加GetNormalSpawnNum方法,获取当前已经生成的Creator生成的所有敌机的数量。在EnemyCreatorMgr中添加_normalTotalNumForSpawnElite,作为一个标志位,标志每一个精英敌人的生成时机。

在Component文件夹中添加EnemyTypeComponent,我们需要获取到当前敌机的类型。然后再修改EnemyView.InitCo方法(Enemy脚本改名为EnemyView)和EnemyCreator.SpawnEnemy方法,将Component动态加载。我们的EnemyType只在EnemyCreatorConfigData数据类中引用过,所以需要修改这两个方法传参。(这段操作目前其实没用)

精英敌人的生成器和普通敌人是不同的,所以我们需要修改EnemyCreatorMgr.SpawnEnemyCreatorMgr.GetNeedSpawnCreator的逻辑,同时添加GetNormalCreatorGetEliteCreator方法,添加两个List,分别缓存当前关卡的Normal敌机生成器和Elite敌机生成器。

自动回收组件

超出屏幕外的敌人和星星都需要自动回收,我们通过自动回收组件来完成这里的逻辑。在Component文件夹中新建AutoDespawnComponent。将EnemyView里面的逻辑转移到这里来,再让EnemyViewStarView挂载这个组件

敌人血条

敌人血条根据敌人的大小动态缩放。敌人血条的Prefab并不属于UI,直接使用10个sprite拼接而成。敌人的血条生成时直接作为Plane的子物体,这样就能和Plane一同由对象池管理。

在Logic——View文件夹内新建EnemyLifeView,我们将大部分逻辑都放到这一个脚本中完成。

EnemyView中加载血条并动态挂载EnemyLifeView

在Logic——View文件夹内新建EnemyLifeItem,挂载在血条每一个sprite上。

子消息系统

之前的消息系统仅支持大的消息,比如Player自己本身的消息,像敌机生命值变化这种消息就不适合了,因为我们不可能分配这么多消息的key,这个时候使用子消息系统。

子消息系统