继上一节完成角色属性参数之后,这一节需要完成角色的攻击参数。并且完善史莱姆的攻击逻辑。
1. 创建 ScriptableObject 脚本/资产文件
和角色属性参数如出一辙,我们首先创建角色攻击参数的 ScriptableObject 脚本。如代码清单 1 所示,我们定义了攻击距离、技能距离、冷却时间、最小/最大攻击力、暴击加成倍率以及暴击几率。
同样的,在 Unity Assets 窗体中创建对应的 ScriptableObject 资产文件。并如图 1 所示,在 Inspector 窗体中指定各个属性的值。
同样的,如代码清单 2 所示,我们编写相应的访问脚本。视频中是把 AttackDataScriptableObject 直接放在先前的角色参数访问脚本中,共有一个访问。但是感觉有点奇怪了,觉得既然都分离开了,就彻底一点;而且视频中原先角色属性参数用访问器,现在攻击参数就直接访问了,看着不统一。
视频中没有这样做。视频中是把 AttackDataScriptableObject 直接放在先前的角色参数访问脚本中,共用一个访问脚本。
1.1 玩家角色使用攻击属性
我们将访问脚本挂载在玩家人物对象上之后,就可以如代码清单 3 一样访问攻击参数了(第 28 行获取到脚本组件)。是否还记得之前第 9 行中的人物攻击距离是硬编码写死的,现在我们把它更改为 AttackRange 参数。
2. 实现敌人攻击逻辑
在为史莱姆创建好攻击属性资产文件,并将相关访问脚本附加到对象上之后,我们开始完善史莱姆的攻击逻辑。
整体的逻辑是,追击着敌人直到在攻击范围之内,停下来攻击玩家。首先是否达到攻击范围可以这样判断:
- bool IsPlayerInAttackRange(GameObject player)
- {
- return Vector3.Distance(player.transform.position, transform.position) <= m_attackData.AttackRange;
- }
史莱姆的攻击也分为普通攻击和暴击,我们先在动画控制器中将攻击对应的动画,以及触发条件设置好。
如图 2 所示,我们在待机状态的基础上设置两个攻击动画,左边是普通攻击的动画,右边是暴击动画。同时创建触发变量 Attack,并创建布尔变量 CriticalHit 区分是否暴击。
一切准备就绪之后,写代码实现攻击逻辑。如代码清单 4 所示,首先获取到属性的访问脚本变量(第 15、16 行)。攻击逻辑在原先的追击逻辑上完善。如果追击到攻击范围之内(第 77 行,IsPlayerInAttackRange),则不播放追击动画,设置 Following 变量为 false(第 79 行),并停止运动(第 80 行)。
和人物攻击一样,敌人攻击也有冷却时间,如果可以攻击,则首先计算此次攻击是否暴击。判断的方法是使用 Random.value,Random.value 会产生 (0,1) 之间的随机数,正好和我们定义暴击率范围是一致的。
攻击的逻辑看到 Attack() 函数(第 115 至 123 行),首先朝向玩家,然后设置 CriticalHit 变量决定是否暴击,接着设置 Attack 变量触发攻击动画。
最后不要忘记让角色不攻击时恢复运动(第 68 行)。
最终实现的效果如图 3 所示,可以看到史莱姆有普通攻击和暴击。