本篇文章是
Unity通过协程实现回合制战斗
的第五部分,需要先读完前文,本篇文章将
发放活动奖品,并设计Buff
特别活动结果
中奖名单

让我们恭喜:
-
Dn2TFL21hB
-
KTUT
-
push
-
Happy sand sculpture
-
RabbitViolet
-
fromlan
透明抽奖过程

中奖须知
请如下中奖的朋友于6月30日前邮件发送您的Unity ID,收货地址,联系方式,周边选择,到
learn
-
cn@unity3d
.
com
周边选择请参照 上篇文章 的开头部分
这次没有中奖的朋友也不要气馁哦~在不久后还会再次发放周边哦~
本文内容
在
上篇文章
,我们设计了结合技能的回合制战斗系统,经过评分区朋友的点出,我发现在随机选择敌方单位的部分,我犯了个小错误,所以本文将会纠正这些错误
同时,在本文我们将设计Buff类型
Bug修复
在之前定义的
private Character[] GetOpponents(Character[] enemy, int range)
方法内,随机排序敌方单位的代码写错了:
之前是这样的:
/// <summary>
/// 选择受击角色
/// </summary>
/// <param name="enemy">全部受击目标</param>
/// <param name="range">技能范围</param>
/// <returns></returns>
private
Character
[
]
GetOpponents
(
Character
[
]
enemy
,
int
range
)
{
//选择敌方存活单位
var
selection
=
enemy
.
ToList
(
)
.
FindAll
(
e
=>
!
e
.
Dead
)
;
//随机排序
selection
.
Sort
(
(
a
,
b
)
=>
Random
.
Range
(
0
,
enemy
.
Length
)
)
;
//如果敌方存活单位多余技能范围人数,就进行裁剪
if
(
selection
.
Count
>
range
)
selection
=
selection
.
Take
(
range
)
.
ToList
(
)
;
return
selection
.
ToArray
(
)
;
}
通过观察代码,我们发现,
随机排序的地方有问题
,这个里面用了C#的
List的Sort方法
,里面返回了一个随机值,实际上这是不对的,
Sort方法
内部
只应该
返回:
-1、0、1
这个方法用于对比匿名委托内的参数A和B,若A和B相等则返回0,若B比A大则返回1,若A比B打则返回-1,而这里我们返回了0到敌方单位总数-1之间的随机数,这是不对的。
实际上我们需要用的方法是Linq里面的OrderBy
,
修改后应该这样:
/// <summary>
/// 选择受击角色
/// </summary>
/// <param name="enemy">全部受击目标</param>
/// <param name="range">技能范围</param>
/// <returns></returns>
private
Character
[
]
GetOpponents
(
Character
[
]
enemy
,
int
range
)
{
//选择敌方存活单位
var
selection
=
enemy
.
ToList
(
)
.
FindAll
(
e
=>
!
e
.
Dead
)
;
//随机排序
selection
=
selection
.
OrderBy
(
c
=>
Random
.
Range
(
0
,
enemy
.
Length
)
)
.
ToList
(
)
;
//如果敌方存活单位多余技能范围人数,就进行裁剪
if
(
selection
.
Count
>
range
)
selection
=
selection
.
Take
(
range
)
.
ToList
(
)
;
return
selection
.
ToArray
(
)
;
}
可以看到,我们对selection这个List进行了
OrderBy
操作,
这样就会针对每个元素生成一个随机值,再通过随机值的数值从小到大排序这些元素
需要注意的是,
OrderBy是Linq的扩展方法
,会
返回
一个
IEnumerable
,我们需要
调用ToList给它转回List
,并
赋值给selection
还有一个需要注意的地方是,这里我们的Character是class,所以这样ToList后其实列表内的每个元素还是原先的元素的引用(指针)
而如果我们这里对 List<struct> 进行了操作,则会对值类型进行拷贝,也就是说ToList后的东西和原先列表内的元素实际上仅仅是数值相同,但是这个对象是新的
这个是C#值类型和引用类型区别导致的原理,若是不太了解但又感兴趣可以搜搜,这里我们不用管值类型和引用类型
这样修改后,我们就可以
正常随机排序敌方单位
了,到此为止,
Bug修复完毕
~
Buff设计
不同于Skill
设计,我们希望
Buff是可以被任意角色共用
的(
技能目前是绑定到角色
身上的,
后期
如果有需要也
会进行拆分
,拆分出可共用的技能)
既然
Buff需要被共用
,那么我们就需要和Character一样,给
Buff变成ScriptableObject并进行配置
(不用ScriptableObject,用Excel配表也行,但我们这里出于对大家友好的目的使用ScriptableObject)
我们先想一想Buff需要什么:
-
Buff名字
-
效果(伤害/治疗/增益/减益/控制)
-
百分比增益减益
-
(伤害/治疗)数值
-
百分比伤害(治疗)/固定伤害(治疗)/施加者当前攻击力伤害(治疗)
-
持续回合数
-
Buff源头(谁施加的这个Buff)
目前能想到的应该只有这些,那么我们先用这些来设计我们的Buff,如果有新的想法我们可以在后期加入~
using
System
;
using
UnityEngine
;
[
CreateAssetMenu
(
fileName
=
"BuffName"
,
menuName
=
"创建Buff"
,
order
=
0
)
]
public
class
BuffData
:
ScriptableObject
{
/// <summary>
/// Buff名
/// </summary>
public
string
buffName
;
/// <summary>
/// Buff效果
/// </summary>
public
BuffEffect
buffEffect
;
/// <summary>
/// 增益/减益百分比,伤害/治疗/控制应忽略这个字段
/// </summary>
public
int
buffPct
;
/// <summary>
/// 伤害/治疗 类型,增益/减益/控制应忽略这个字段
/// </summary>
public
BuffType
buffType
;
/// <summary>
/// Buff伤害/治疗量,增益/减益/控制应忽略这个字段
/// </summary>
public
int
buffDmg
;
/// <summary>
/// Buff持续回合数
/// </summary>
public
int
round
;
/// <summary>
/// 将Buff配置数据转Buff类型,需要传施法者作为参数
/// </summary>
/// <param name="enforcer"></param>
/// <returns></returns>
public
Buff
ToBuff
(
Character
enforcer
)
{
return
new
Buff
{
BuffName
=
buffName
,
BuffEffect
=
buffEffect
,
BuffPct
=
buffPct
,
BuffType
=
buffType
,
BuffDmg
=
buffDmg
,
Round
=
round
,
Enforcer
=
enforcer
}
;
}
}
public
class
Buff
{
/// <summary>
/// Buff名
/// </summary>
public
string
BuffName
;
/// <summary>
/// Buff效果
/// </summary>
public
BuffEffect
BuffEffect
;
/// <summary>
/// 增益/减益百分比,伤害/治疗/控制应忽略这个字段
/// </summary>
public
int
BuffPct
;
/// <summary>
/// 伤害/治疗 类型,增益/减益/控制应忽略这个字段
/// </summary>
public
BuffType
BuffType
;
/// <summary>
/// Buff伤害/治疗量,增益/减益/控制应忽略这个字段
/// </summary>
public
int
BuffDmg
;
/// <summary>
/// Buff持续回合数
/// </summary>
public
int
Round
;
/// <summary>
/// 施法者
/// </summary>
public
Character
Enforcer
;
}
[
Serializable
]
public
enum
BuffEffect
:
byte
{
伤害
=
0
,
治疗
=
1
,
增益
=
2
,
减益
=
3
,
控制
=
4
,
}
public
enum
BuffType
:
byte
{
百分比
=
0
,
固定
=
1
,
当前攻击力
=
2
}
这里我们对配置的
Buff数据不添加施法者字段
,因为这个应该是
由施法时动态赋值
的,所以我们在将
Buff配置数据转Buff类型时进行操作
(不懂为什么要将配置导出来的朋友可以看看本系列第一篇文章)
接下来我们在Assets目录下创建BuffDatas目录,进入后右键创建Buff数据即可:

比如这里我创建了一个叫做
中毒的Buff
,
每回合损失总生命值的10%
,持续
3回合

到这里,我们本篇文章就讲完了~
下篇预告
下篇文章,我们将:
-
给角色数据配置可施展的Buff
-
给角色类型创建当前生效中的Buff字段
-
每回合结算Buff效果
最后
感谢大家的支持,下一篇文章预计在接下来1~2周内发表,欢迎大家在评论区发言哦~
P.S. 中奖的朋友记得领奖哦~