Unity通过协程实现回合制战斗(五、Buff设计)

本文修复了Unity回合制战斗中敌方单位随机排序的错误,并引入Buff设计,支持角色共用。通过修正代码和创建BuffData与Buff类,为角色添加可配置的持久效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇文章是 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. 中奖的朋友记得领奖哦~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值