帧同步--Bullet弹道技能实现¶
BUFF逻辑和BUFF比较相似¶
追踪类型¶
- 目标追踪
- 可被阻挡
- 不可阻挡(可能有路径穿透伤害及效果)
- 方向射出
- 可被阻挡
- 不可阻挡(可能有路径穿透伤害及效果)
子弹配置与逻辑层初始化¶
子弹配置在哪里设置? - 技能如果需要发射子弹,就设置在技能的配置里面。
子弹拿到配置,需要单独初始化的东西有: - Bullet大小 - 子弹初速度 - 子弹位置(包括计算配置中的高度、偏移)。 - 子弹延迟 并且需要初始化 - 上一次的位置,用于体积扫琼计算
子弹生命状态¶
对于子弹,其和buff的运行相似, 基类都是用的LogicUnit的LogicInit,创建后立刻调用: - 无延迟:切换到Start - 有延迟:切换到Delay,并在Tick处理delay逻辑 LogicTick还会写有End的逻辑处理。
对于子弹基类,我们的Tick只需要处理两种状态: - Start:处理Start逻辑 - 通用逻辑:加载子弹资源并初始化表现层 - Tick:处理Tick逻辑,但是具体实现全部交给子类。 而对于子弹:End的触发则是碰撞检测成功时进行切换 - End: - 通用逻辑:销毁表现层的物体。 - 判断目标状态:造成伤害。 - None: - 无用状态:交由子弹管理轮询检测,用来删除。
位置同步与平滑¶
由于子弹肯定是高速移动的物体,那么一定需要进行逻辑位置同步和平滑。
不过这个和角色用一样的逻辑,就不单独讲了。
☆子弹体积扫描算法(高速运动防穿透)¶
子弹体积扫描算法的核心:根据前一帧和当前帧位置和子弹大小,计算出新的方形包围盒ABCD。然后和目标碰撞体再计算碰撞。
先计算出预测位置: - 先算出子弹移动的方向(目标/直线) - 再根据运动曲线去调整方向 - 再计算出当前预测的位置,
子弹扫描算法计算:主要是根据前一帧保留的位置计算得出 - 中心点O:先通过前后两个位置计算出新碰撞体的中心点O - 碰撞体长度offset:前后两位置的位移。 - 碰撞体体积:x为碰撞体长度的一半、y为0(2D),z为子弹大小 - 碰撞体轴向: 也是根据offset、y轴,以及offset和y轴叉乘组成。 - 更新lastPos:算完之后,更新前一帧位置为当前帧位置。
补充:弹道显示DEBUG¶
之前实习用过gizmos写过位置,非常不直观。
现在有了新的方法:直接新建一个带碰撞盒的正方体,直接根据碰撞体大小和轴向创建gameobject,关掉meshrendereer,弹道显示非常直观,还能精准的看出碰撞过程。
我还设置了一个UnityEditor宏时打开弹道显示,打包出来后应该完全关掉这部分测试的逻辑
子弹管理¶
子弹不像buff那样和人物强绑定,就直接放在战斗管理器进行管理了。 - 轮询执行TICK - 轮询检测none,执行删除。 - 子弹添加:作为战斗系统的API供外部调用
常见子弹实现¶
目标追踪子弹TargetBullet¶
实体配置: - 击中高度:首先,我们得给实体设置个跟踪的高度,用来计算最终跟踪的位置 逻辑初始化实现: - 每帧 计算方向,计算初始位置与偏移 - 预测与平滑 - 体积扫描算法判断碰撞。
方向子弹DirectionBullet¶
方向子弹与目标无关,仅和初始射出的方向有关 - 检测子弹释放方式: - UI指定方向:仅改方向 - UI指定位置: - 设置目标点,并初始化一个子弹大小的圆形碰撞体用于检测到达, - 根据目标点修改方向 - 阻挡检测: - 被阻挡,则选择范围里最近的那个 - 没有被阻挡,则按照目标配置到目的地时再触发效果。 -
延迟、偏移设置¶
有些子弹不是Skill的logicInit那样直接发射原始配置的子弹的。 由于一些子弹可能会做点延迟和偏移的效果,因此提供一些外部API,在非常规技能下生成子弹时进行修改调用(比如BUFF生成子弹)。
☆特殊轨道(方向修改、曲线等)设置¶
原理即初始设置方向,然后每帧根据曲线去更新方向和位置 - 万箭齐发跟踪效果:可以用伪随机数来造成子弹的随机偏移。 - 确定曲线:提供方程进行更新 - 确定直线:设置方向(仅非跟踪才可以)