一、首先创建一个buff信息结构体
public struct BuffInfo
{
public int buffId; //buffid
public int[] time; //buff生效时间
public int[] attack; //buff的伤害
public string anim; //buff动画
public float range; //buff伤害范围
public int overTimes; //buff叠加次数
public bool refresh; //刷新持续时间
}
二、创建一个buff基类
public class BaseBuff : MonoBehaviour
{
//buff信息
BuffInfo mBuffInfo;
//当前英雄
Role mTarget;
void Awake()
{
//拥有该buff的英雄
mTarget = gameObject.GetComponent<Role>();
}
void Start()
{
}
/// <summary>
/// 装配buff数据
/// </summary>
public void AssembleData(int buffId)
{
//装配buff数据
mBuffInfo.buffId = 1;
mBuffInfo.time = new int[] { 1, 1, 1, 1 };
mBuffInfo.attack = new int[] { 0, -1, -2, -3 };
}
/// <summary>
/// Buff开始
/// </summary>
public void Begin()
{
//播放buff动画
PlayAnimation();
//开启协程,造成伤害
StartCoroutine("CauseDamage");
}
/// <summary>
/// 播放动画
/// </summary>
private void PlayAnimation()
{
}
/// <summary>
/// Buff结束
/// </summary>
public void End()
{
//由于协程开启了,可能协程尚未结束,需要移除此buff
StopCoroutine("CauseDamage");
//销毁组件
Destroy(this);
}
/// <summary>
/// buff产生伤害
/// </summary>
/// <returns></returns>
IEnumerator CauseDamage()
{
//循环遍历数组造成伤害
for (int i = 0; i < mBuffInfo.time.Length; i++)
{
//人物死亡
if (mTarget.GetRoleInfo().blood <= 0)
{
//关闭协程
StopCoroutine("CauseDamage");
}
else
{
//目标掉血
mTarget.IncreaseBlood(mBuffInfo.attack[i]);
}
//等待时间
yield return new WaitForSeconds(mBuffInfo.time[i]);
}
//buff结束,人物没死
if (mTarget.GetRoleInfo().blood > 0)
{
//关闭协程
StopCoroutine("CauseDamage");
//移除buff
mTarget.RemoveBuff(mBuffInfo.buffId);
}
}
/// <summary>
/// 获取buff信息
/// </summary>
/// <returns></returns>
public BuffInfo GetInfo()
{
return mBuffInfo;
}
}
三、最后有一个buff管理器
public class BuffMgr
{
//角色身上buff存储器
//同一个buff可能在一个对象上添加多次
//先进先出
public Dictionary<int, Queue<BaseBuff>> mBuffDic;
//目标对象
private ATNRole mTarget;
public BuffMgr(ATNRole target)
{
mBuffDic = new Dictionary<int, Queue<BaseBuff>>();
mTarget = target;
}
/// <summary>
/// 对角色施加Buff
/// </summary>
/// <param name="buff"></param>
public void Add(int buffId)
{
//如果角色已经施加了此Buff
if (mBuffDic.ContainsKey(buffId))
{
//取队列的首元素,并读取它
BuffInfo buffInfo = mBuffDic[buffId].Peek().GetInfo();
//如果叠加次数没有达到
//有叠加次数的技能一般每层都有一个计时器,新技能不会刷新旧技能的持续时间
if (mBuffDic[buffId].Count < buffInfo.overTimes)
{
AddBuff(buffId);
}
//不叠加,但是刷新持续时间,新buff替换旧buff
if (buffInfo.refresh)
{
//移除原先的buff
Remove(buffId);
//添加新buff
AddBuff(buffId);
}
}
//没有施加Buff
else
{
//首先创建队列
mBuffDic[buffId] = new Queue<BaseBuff>();
//添加新buff
AddBuff(buffId);
}
}
/// <summary>
/// 添加Buff
/// </summary>
private void AddBuff(int buffId)
{
//添加buff组件
BaseBuff buff = mTarget.gameObject.AddComponent<BaseBuff>();
//根据id对buff进行改造
buff.AssembleData(buffId);
//buff开始
buff.Begin();
//入列
mBuffDic[buffId].Enqueue(buff);
}
/// <summary>
/// 移除角色的所有Buff
/// </summary>
public void Clear()
{
foreach (int buffId in mBuffDic.Keys)
{
//从容器中移除
Remove(buffId);
}
}
/// <summary>
/// 移除角色身上指定的Buff
/// </summary>
public void Remove(int buffId)
{
//如果存在Buff
if (mBuffDic.ContainsKey(buffId))
{
//buff结束
Queue<BaseBuff> buffQue = mBuffDic[buffId];
for (int i = 0;i < buffQue.Count;i++)
{
buffQue.Peek().End();
//出列
buffQue.Dequeue();
}
//从容器中移除
mBuffDic.Remove(buffId);
}
}
}
四、使用
public class Role
{
public BuffMgr mBuffMgr;
public virtual void Start()
{
//buff管理器
mBuffMgr = new BuffMgr(this);
}
// 角色身上添加buff
public void AddBuff(int buffId)
{
mBuffMgr.Add(buffId);
}
// 角色身上移除Buff
public void RemoveBuff(int buffId)
{
mBuffMgr.Remove(buffId);
}
}