概述
子弹系统,是GCS中,用于驱动远程战斗,法术,Projectile的系统。
我是艾尔登法环的重度玩家,我希望我的子弹系统能像艾尔登法环的子弹系统一样优秀。因此我通过很多资料学习艾尔登法环中的法术如何工作,并在UE中实现类似的。
你在这里可以看到艾尔登法环的子弹系统是多么优秀,而我的版本会越来越接近它:https://www.youtube.com/watch?v=rIDQSJ39JUM
在GCS中,你可以快速添加各种各样的子弹,以实现不同的效果。
子弹定义
真实项目中,你可能会定义成千上万个子弹,所以,子弹由DataTable进行管理,且所有对象的引用都采用的软对象引用,因此你不用担心我写的代码使你的项目爆炸。
你通过创建结构体类型为GCS_BulletDefinition的DataTable资产,来管理和编辑你项目中的所有子弹。

每一行代表一个子弹定义,每一个定义中你可以配置很多参数,其中最重要的参数如下(其余的参数拥有注释,不再这里赘述):
BulletActorClass:指定了该子弹定义对应的子弹ActorClass,你可以选择默认提供的,或者针对特殊的子弹,定义特殊的子弹实例。
BulletCount:这个用于控制使用该定义生成子弹时,实际会产生多少个子弹实例,配合发射配置(LaunchConfiguration),你可以实现很多有趣的子弹效果。
AttackDefinition:你通过这个选项来选择不同的攻击定义,在子弹击中目标后,会根据攻击定义中指定的信息为目标应用游戏效果。
子弹实例
GCS提供一个C++编写的GCS_BuleltInstance作为所有子弹的父类,并处理性能要求比较严苛的逻辑,同时提供了预置的蓝图子类(BP_GCS_Projectile),以方便拓展。
默认实现足够通用,通常情况下你不需要再创建新的蓝图子类。
通过动画触发子弹
请查看这里:攻防流程
通过蓝图触发子弹
在系统底层,提供了GCS Bullet Subsystem(子弹子系统),因此你可以

GCS的子弹Actor还实现了GCS_EffectCauser
接口,意味着你可以在子弹发射前,为其设置已经创建好的游戏效果实例。
当子弹击中目标后,会应用传入的游戏效果实例。

AttackRequest是一个默认实例化的对象,因此当你在任意蓝图建立一个AttackRequest类型的变量时,你是在创建一个AttackRequest的实例,而不是引用一个已经存在的AttackRequest对象。
实例化的Request会跟随所在的蓝图进行保存。
子弹对象池
所有创建的子弹实例,都通过对象池进行管理。简单来说,一个子弹完成它的作用后,功能会被禁用且缓存起来,每当需要创建新的子弹时,会优先从已经缓存的子弹找到可用的子弹,然后重新启用功能。这样可以极大的缓解频繁生成/销毁子弹所带来的性能消耗。
因此,当你自定义你的子弹Actor时,你需要注意:
子弹实例的BeginPlay和Endplay通常只会调用一次,但是OnBulletBeginplay和OnBulletEndplay会反复调用。

子弹客户端预测
GCS也支持客户端预测,意味着在较高延迟的网络环境下,你可以在本地预先生成子弹,客户端预测的子弹会和服务端版本进行合并。
此功能还在开发中,功能稳定后会编写更多文档。