Buff可以理解成是一种技能,这种技能加持在一个游戏对象身上,增加这种Buff所特有的属性,包括持续时间,次数等,常用语游戏里面的技能加减血,加减速度等
1.所有Buffer的类型基类
========================================
using UnityEngine;
using System.Collections;
using System;
//所有Buffer的类型基类,抽象类可以包含抽象方法和普通方法,
//但是必须要在子类里实现所有基类里面的抽象方法
public abstract class BufferStateBase
{
// 1.当前状态控制的游戏对象是谁
public Transform CurrCtrl {
get;
set;
}
// 2.当前Buffer的类型 -> Buffer? Debuffer? PerBuffer? PerDeBuffer?
public object CurrBufferType {
get;
set;
}
// 3.当前Buffer具体值 -> SpeedUp? Disarm?
public object CurrBurrferState {
get;
set;
}
// 4.当前buffer的具体描述, 注意一个抽象方法,在继承它的子类里必须实现他一
public abstract string CurrBufferInfo {
get;
}
// 5.当前Buffer所接受的具体参数,注意是BufferArgs(里面的参数有一个脚本来定义)类型的
public BufferArgs CurrArgs {
set;
get;
}
//一系列回调
public abstract bool OnEnter ();
public abstract bool OnUpdate ();
public abstract bool OnExit ();
}
2.当前
Buffer所具有的具体参数
using UnityEngine;
using System.Collections;
public class BufferArgs
{
// 是否允许重复添加?
// false: 不允许重复添加, 但是更新持续时间,意思是当添加一个Buffer时,
//如果已经添加了相同的Buffer,那么就只会重新刷新持续时间,而不会重复添加
// true: 允许重复添加, 两个相同的buffer同时发挥作用
public bool m_addition = false;
// 如果是周期性的buffer, 每一次间隔是多少?
public float m_Timer;
// 如果是按次数计量
public int m_Times;
// 能否被驱散
public bool m_Dispel;
// 持续时间
public float m_ContinuousTime;
// 是否结束
public bool isOver = false;
//其他一些可能用到的参数
public float m_fValue1;
public float m_fValue2;
public float m_fValue3;
public float m_fValue4;
public string m_sValue1;
public string m_sValue2;
public string m_sValue3;
public string m_sValue4;
public bool m_bValue1;
public bool m_bValue2;
public bool m_bValue3;
public bool m_bValue4;
}
3. 这个类中存放各种枚举的类型
public class BufferType
{
// 正面buffer
public enum Buffer
{
AllType,
//加速的Buffer
BufferSpeedUp,
//无敌Buffer
BufferInvincible,
}
// 负面buffer
public enum DeBuffer
{
AllType,
//减速的Buffer
BufferSlowDown,
//除装的Buffer
BufferDisarm,
}
// 周期性的正面buffer
public enum PerBuffer
{
AllType,
//持续加血的Buffer
BufferAddBlood,
//持续加魔法值的Buffer
BufferAddMagic,
}
// 周期性的负面buffer
public enum PerDeBuffer
{
AllType,
//持续减血的Buffer
BufferCRBlood,
}
}
4.加速的Buffer
using UnityEngine;
using System.Collections;
//继承自Buffer基类的,加速的Buffer
public class BufferSpeedUp : BufferStateBase
{
#region implemented abstract members of BufferStateBase
//重写基类中进入Buffer的回调
public override bool OnEnter ()
{
UnityEngine.Debug.Log ("进入加速Buffer");
return true;
}
//重写基类中Buffer持续的回调
public override bool OnUpdate ()
{
//CurrArgs.m_ContinuousTime,表示buffer持续时间CurrArgs是BufferArgs类型的
UnityEngine.Debug.Log ("持续在加速Buffer中, 剩余时间:" + CurrArgs.m_ContinuousTime);
if ((CurrArgs.m_ContinuousTime -= Time.deltaTime) <= 0) {
CurrArgs.isOver = true; //表示会否结束,True表示结束
}
return true;
}
//重写离开Buffer的回调
public override bool OnExit ()
{
UnityEngine.Debug.Log ("离开了加速Buffer");
return true;
}
//当前Buffer的简述
public override string CurrBufferInfo {
get {
return "这是加速Buffer, 提速为:" + CurrArgs.m_fValue1;
}
}
#endregion
}
5.Buffer控制器
using UnityEngine;
using System.Collections.Generic;
using System;
//Buffer控制器
public class BufferMgr
{
// 1.该控制器不需要挂载到游戏对象身上
// 2.和人物控制不同, 不同的buffer之间可以同时工作
// 3.所以我们需要一个容器, 里面存放所有的buffer状态
// 4.我们在每一帧, 按照添加的顺序, 不停的调用每一个状态的OnUpdate方法
// 5.根据状态的m_addition条件来判断是否更新buffer的持续时间
// 公开的接口
// 受到buffer系统影响的游戏对象
public Transform CurrCtrl {
get;
set;
}
// 构造方法
public BufferMgr (Transform trans)
{
CurrCtrl = trans;
}
// Buffer容器
private List<BufferStateBase> m_bufferList = new List<BufferStateBase> ();
// 以下方法是我们的设计, 面向用户的
// 尽可能的全, 并且易于理解和使用
// 1.添加一个新的Buffer(包括刷新或者重新添加)
private BufferStateBase BufferCreate (object buffer, BufferArgs bufferArgs)
{
//直接创建BufferstateBase类型的变量,于BufferSpeedUp是一样的
//Activator.CreateInstance创建一个实例
BufferStateBase newBuffer =
Activator.CreateInstance (
Type.GetType (buffer.ToString ())
)
as BufferStateBase;
//具体参数赋值
newBuffer.CurrArgs = bufferArgs;
// 控制的游戏对象(前面定义的Buffer影响到的游戏对象)
newBuffer.CurrCtrl = CurrCtrl;
//当前Buffer的类型,负面Buffer还是正面Buffer
newBuffer.CurrBufferType = buffer.GetType ();
//当前Buffer的具体值
newBuffer.CurrBurrferState = buffer;
return newBuffer;
}
private void BufferAddBase (object buffer, BufferArgs bufferArgs)
{
// 实例化一个Buffer
BufferStateBase newBuffer = BufferCreate (buffer, bufferArgs);
// 判断该buffer是否应该添加到容器中
if (newBuffer.CurrArgs.m_addition == true) {
// 添加到容器中
newBuffer.OnEnter ();
m_bufferList.Add (newBuffer);
} else {
// 判断该状态在容器中是否存在
if (BufferCheckExistsBase (buffer)) { // 存在, 更新作用时间
//这样用到一个委托(一种缩写形式),在列表里找是否存在Buffer类型的Buffer,然后复制给oldBuffer
BufferStateBase oldBuffer = m_bufferList.Find (delegate(BufferStateBase obj) {
return obj.CurrBurrferState.Equals (buffer);
});
//如果oldBuffer不为空,表示容器中存在了于该Buffer相同的Buffer
if (oldBuffer != null) {
//那么及更新一下作用时间,也就是重新赋一下值
oldBuffer.CurrArgs.m_ContinuousTime = newBuffer.CurrArgs.m_ContinuousTime;
}
} else { // 不存在, 直接添加进去
// 添加到容器中
newBuffer.OnEnter ();
m_bufferList.Add (newBuffer);
}
}
}
public void BufferAdd (BufferType.Buffer buffer, BufferArgs bufferArgs)
{
// 根据buffer参数创建一个新的BufferStateBase对象
BufferAddBase (buffer, bufferArgs);
}
public void BufferAdd (BufferType.DeBuffer buffer, BufferArgs bufferArgs)
{
BufferAddBase (buffer, bufferArgs);
}
public void BufferAdd (BufferType.PerBuffer buffer, BufferArgs bufferArgs)
{
BufferAddBase (buffer, bufferArgs);
}
public void BufferAdd (BufferType.PerDeBuffer buffer, BufferArgs bufferArgs)
{
BufferAddBase (buffer, bufferArgs);
}
// 2.移除某一种Buffer, 或者某一类Buffer
private void BufferRemoveBase (object bufferType = null)
{
if (bufferType == null) {
m_bufferList.RemoveAll (delegate(BufferStateBase obj) {
return (obj.OnExit () || true);
});
return;
}
// 删除一类Buffer还是删除一个Buffer?
if ((int)bufferType == 0) {
m_bufferList.RemoveAll (delegate(BufferStateBase obj) {
return obj.CurrBufferType.Equals (bufferType.GetType ()) && (obj.OnExit () || true);
});
} else {
m_bufferList.RemoveAll (delegate(BufferStateBase obj) {
return obj.CurrBurrferState.Equals (bufferType) && (obj.OnExit () || true);
});
}
}
public void BufferRemove (BufferType.Buffer buffer)
{
BufferRemoveBase (buffer);
}
public void BufferRemove (BufferType.DeBuffer buffer)
{
BufferRemoveBase (buffer);
}
public void BufferRemove (BufferType.PerBuffer buffer)
{
BufferRemoveBase (buffer);
}
public void BufferRemove (BufferType.PerDeBuffer buffer)
{
BufferRemoveBase (buffer);
}
public void BufferRemove ()
{
BufferRemoveBase ();
}
// 3.检查某个Buffer是否存在
private bool BufferCheckExistsBase (object buffer)
{
BufferStateBase findBuffer = m_bufferList.Find (delegate(BufferStateBase obj) {
return obj.CurrBurrferState.Equals (buffer);
});
//三目运算符,判断是否存在,存在返回Ture,不存在返回False
return findBuffer == null ? false : true;
}
public bool BufferCheckExists (BufferType.Buffer buffer)
{
return BufferCheckExistsBase (buffer);
}
public bool BufferCheckExists (BufferType.DeBuffer buffer)
{
return BufferCheckExistsBase (buffer);
}
public bool BufferCheckExists (BufferType.PerBuffer buffer)
{
return BufferCheckExistsBase (buffer);
}
public bool BufferCheckExists (BufferType.PerDeBuffer buffer)
{
return BufferCheckExistsBase (buffer);
}
// 4.驱动OnUpdate的方法
public void Updata ()
{
// 调用每个Buffer的update方法
m_bufferList.Find (delegate(BufferStateBase obj) {
return (obj.OnUpdate () || true);
});
// 检查结束的Buffer, 然后移除之
m_bufferList.RemoveAll (delegate(BufferStateBase obj) {
return obj.CurrArgs.isOver == true && (obj.OnExit () || true);
});
}
}
6.Buffer管理,挂在游戏对象身上
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public BufferMgr m_bufferMgr; //接受一个Buffer控制器
void Start ()
{
m_bufferMgr = new BufferMgr (transform);
}
void Update ()
{
//每帧调用依次Update
m_bufferMgr.Updata ();
if (Input.GetKeyDown (KeyCode.Alpha1)) {
BufferArgs args = new BufferArgs ();
args.m_fValue1 = 0.2f;
args.m_addition = false;
args.m_ContinuousTime = 3;
m_bufferMgr.BufferAdd (BufferType.Buffer.BufferSpeedUp, args);
}
if (Input.GetKeyDown (KeyCode.Alpha2)) {
m_bufferMgr.BufferRemove (BufferType.Buffer.BufferSpeedUp);
}
if (Input.GetKeyDown (KeyCode.Alpha3)) {
m_bufferMgr.BufferRemove ();
}
}
}