前言

​ 先开个坑,关系到毕业设计的实现。

游戏类型:

战旗类型、分为单机和联网,单机下怪物由AI树驱动,联网进行玩家对战

暂定的网络同步思路

  • 状态同步方式
    • 位置方面:客户端Unit每隔一段时间将自身的位置、朝向、速度发送给服务器,服务器计算出最终结果后进行广播操作,所有Units对位置结果进行插值处理
      12/19更新:现已通过A*方式进行寻路,所以客户端上传位置指令后服务器进行一定的校验、记录后即可进行转发操作,由客户端通过A*寻路移动到指定格子。
    • 状态方面(技能、动画等):利用一个状态包来进行转发广播操作,与位置包分开处理
      12/19更新:因为制作的是战旗类型游戏,所以调整同步方式为同步玩家的输入指令,由服务器计算伤害数值、角色属性等变化进行广播操作(现在已将伤害的显示逻辑与表现逻辑分离)提供给客户端进行表现。

目前进度:

  • 弃用ET的自带UI,加入了EGUI的基于ET的UI框架并针对其进行修改和适配,加入UI栈、UI队列等
  • 采用ET框架实现A*寻路算法,将具体寻路功能拆分为在zoneScene中全局的A*地图GridComponent组件与移动控制组件ControlComponent
  • 初步加入技能系统,可以获取移动/技能范围并对对应格子移动/释放,技能、角色等属性采用导表的方式,方便后期修改
  • 战斗场景搭建,并针对画面进行了Bloom、环境光遮蔽等后处理
  • 战斗玩家Unit、怪物Unit设计完成,通过彼此的BattleComponent进行交互,符合ECS思路

12/19更新:

  • RoundMgrComponent实现回合管理,回合顺序初步通过角色自身的速度属性进行排序,后期配合Buff技能会在回合中打乱战斗角色的回合顺序。

  • 加入Buff状态机以及每个角色的BuffComponent即Buff状态组件,可对角色进行Buff的添加、移除(如加攻、防等机制),可实现每回合开始前的Buff判定Tick()(如中毒、流血等机制)

  • 实现四叉树场景管理,对于不在摄像机内的场景Object进行剔除,优化内存

具体文章:基于ET的四叉树场景管理组件

四叉树场景管理

  • 实现技能派生机制(技能组),在策划表填写时可以填写某技能的子技能,在实际调用时会顺序使用其派生技能,因此在使用组合技能时无需通过Animator对每个技能动画进行再组合
    技能表的部分参数:
    image-20211219145924703

  • 实现可视化模块管理,包括伤害数值/特效模块、相机控制模块、四叉树场景管理模块、声音模块等。
    其中SoundModule音频管理参考自GameFramework中的思路。
    具体文章:
    基于ET的模块化管理及其声音模块

  • 优化UI流程,添加场景切换加载Loading界面,增加UI淡入淡出效果,新增血条展示,人物状态栏、技能栏等

  • 实现shader的剔除效果模拟slider,新增子UI预置ESNormalSlider(基于Unity的Slider),ESSlider(基于Shader剔除),实现shader的消融效果等。
    具体文章:
    Shader:透明度混合,平面下的外/内轮廓,立体下的外轮廓,菲涅尔现象,内发光现象总和
    Shader剔除模拟Slider效果

  • 实现场景地图障碍物(具体障碍物prefab会在预置Obstacle Prefab中随机选择)、怪物、角色自定义生成,方便随时进行地图信息调整。后期拟定会在角色战斗前由玩家自定义调整角色位置。
    地图表格:
    image-20211219152210832

  • 实现怪物AI行为树,提供Sequence、Selector、ETTaskAction等多节点任意组合,提供RandomSequence实现怪物逻辑的随机性:

    image-20211219152410501

    怪物一般逻辑:如果范围内有敌人则攻击,若没有则向其仇恨玩家移动(1,最大移动距离),若无仇恨玩家则向第一个地方角色随机移动。仇恨机制表示上一次攻击其的玩家。
    代码逻辑:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    m_Ai.OpenBranch(
    BT.If(() =>
    {
    if (bc.lastAttackedUnit!=null)
    {
    CharacterPropertyComponent lastcpc = bc.lastAttackedUnit.GetComponent<CharacterPropertyComponent>();
    if (lastcpc!=null)
    {
    return !lastcpc.isDead;
    }
    }
    return false;
    }).OpenBranch(
    BT.RunETTask(() => this.OnAttackToUnit(baseUnit, bc.lastAttackedUnit))
    ),
    BT.If(() => { return enemyCells.Count > 0;}).OpenBranch(
    BT.RunETTask(() => this.OnAttackToPoint(baseUnit,enemyCells.First()))
    ),
    BT.If(() => { return enemyCells.Count == 0;}).OpenBranch(
    BT.RunETTask(() =>
    {
    //获取随机脚步
    Random.InitState(DateTime.Now.Millisecond);
    int footStep = Random.Range(1, cpc.moveRange);

    //找到距离某个角色的最短路径
    //TODO:后续应该优化,当前找到的默认是第一个生成的角色
    BaseUnitComponent buc = aiInput.DomainScene().GetComponent<BaseUnitComponent>();
    BaseUnit unit=buc.GetFirstPlayerUnit();

    CharacterPropertyComponent unit_cpc = unit.ConcreteUnit.GetComponent<CharacterPropertyComponent>();
    return this.OnChasePoint(baseUnit,unit_cpc.PointPos,footStep);
    })
    )
    );
  • 实现技能释放的表现和逻辑分离,在释放技能前进行伤害数值计算,后期在Server中单独执行伤害技能的伤害数值计算、Buff逻辑计算、并调整角色属性,客户端仅做表现

    • 每个技能分为Action和Effect,Action控制使用者动画播放,Effect控制技能特效、战斗数值等表现。

image-20211219160917057

  • 游戏主界面设计,目前已完成初步主界面UI,后续拟定通过Camera在游戏实际场景中的巡逻作为背景

    image-20211219162109577