(六)模板模式
模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,是一种基于继承的代码复用技术。
相关链接:https://blog.csdn.net/lovelion/article/details/8299794
模板模式代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TemplateMethodDemo:MonoBehaviour
{
void Start()
{
IPeople nor = new NorthPeople();
nor.Eat();
}
}
public abstract class IPeople
{
public void Eat()
{
OrderFoods();
EatSomething();
PayBill();
}
public void OrderFoods() {
Debug.Log("—点单");
}
public abstract void EatSomething();
public void PayBill()
{
Debug.Log("—买单");
}
}
public class NorthPeople : IPeople
{
public override void EatSomething()
{
Debug.Log("我在吃面条");
}
}
public class SouthPeople : IPeople
{
public override void EatSomething()
{
Debug.Log("我在吃米饭");
}
}
对武器的开火方法进行改写:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class IWeapon
{
protected int mAtk;//最大攻击力
protected float mAtkRange;//最大攻击范围
protected int mAtkPlusValue;//暴击
protected GameObject mGameObject;//武器模型
protected ICharacter mOwner;//武器持有者
protected ParticleSystem mParticle;//武器特效
protected LineRenderer mLineRender;//武器射线
protected Light mLight;
protected AudioSource mAudioSource; //音效
protected float mEffectDisplayTime;//特效显示时间
public void Fire(Vector3 targetPos)
{
//显示枪口特效
GunShootEffect();
//显示子弹轨迹特效
GunBulletEffect(targetPos);
//设置特效显示时间
SetDisplayEffectTime();
//播放声音
PlayAudioSources();
}
public void Update()
{
if (mEffectDisplayTime > 0)
{
mEffectDisplayTime -= Time.deltaTime;
if (mEffectDisplayTime <= 0)
{
DisableEffect();
}
}
}
protected abstract void SetDisplayEffectTime();
protected virtual void GunShootEffect()
{
DoGunShootEffect();
}
protected void DoGunShootEffect()
{
mParticle.Stop();
mParticle.Play();
mLight.enabled = true;
}
protected abstract void GunBulletEffect(Vector3 targetPos);
protected void DoGunBulletEffect(Vector3 targetPos, float Width)
{
mLineRender.enabled = true;
mLineRender.startWidth = Width;
mLineRender.endWidth = Width;
mLineRender.SetPosition(0, mGameObject.transform.position);
mLineRender.SetPosition(1, targetPos);
}
protected abstract void PlayAudioSources();
protected void DoPlayAudioSources(string str)
{
string clipName = str;
AudioClip clip = null; //TODO 后面会对资源加载进行管理,先不做改动
mAudioSource.clip = clip;
mAudioSource.Play();
}
//结束特效显示
private void DisableEffect()
{
mLight.enabled = false;
mLineRender.enabled = false;
}
}
其子类重写方法,如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponGun: IWeapon
{
protected override void GunBulletEffect(Vector3 targetPos)
{
DoGunBulletEffect(targetPos,0.1f);
}
protected override void PlayAudioSources()
{
DoPlayAudioSources("GunShot");
}
protected override void SetDisplayEffectTime()
{
mEffectDisplayTime = 0.2f;
}
}
(七)有限状态机FSM:
相关链接http://wiki.unity3d.com/index.php/Finite_State_Machine
开发战士状态的抽象接口 ISoldierState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SoldierTransition
{
NullTransition,
SeeEnemy,
CanAttack,
NoEnemy,
}
public enum SoldierStateID
{
NullState,
Idle,
Chase,
Attack
}
public abstract class ISoldierState
{
protected Dictionary<SoldierTransition, SoldierStateID> mapDict = new Dictionary<SoldierTransition, SoldierStateID>();
protected ICharacter mCharacter; //属于哪个角色
protected SoldierFSMSystem mSoldierFSMSystem;
protected SoldierStateID mSoldierStateID;
public SoldierStateID stateID { get { return stateID; } }
public ISoldierState(SoldierFSMSystem fsm, ICharacter c)
{
this.mSoldierFSMSystem = fsm;
mCharacter = c;
}
public void AddTransition(SoldierTransition tran, SoldierStateID id)
{
if (tran == SoldierTransition.NullTransition)
{
Debug.Log("SoldierState Error : tran不能为空"); return;
}
if (id == SoldierStateID.NullState)
{
Debug.Log("SoldierState Error : id不能为空"); return;
}
if (mapDict.ContainsKey(tran))
{
Debug.Log("SoldierState Error :"+tran+"已经添加过了"); return;
}
mapDict.Add(tran, id);
}
public void DelectTransition(SoldierTransition tran, SoldierStateID id)
{
if (tran == SoldierTransition.NullTransition)
{
Debug.Log("SoldierState Error : tran不能为空"); return;
}
if (mapDict.ContainsKey(tran))
{
mapDict.Remove(tran);
return;
}
Debug.Log("SoldierState Error : id was not on the state's transition list");
}
public SoldierStateID GetPutoutStateID(SoldierTransition tran)
{
if (mapDict.ContainsKey(tran))
{
return mapDict[tran];
}
return SoldierStateID.NullState;
}
public virtual void DoBeforeEntering() { }
public virtual void DoBeforeLeaving() { }
/// <summary>
/// 控制行为
/// </summary>
public abstract void Act(List<ICharacter> targets);
/// <summary>
/// 此方法决定状态是否应该转换到其列表中的另一个状态
/// </summary>
/// <param name="targets">要跟随/攻击的目标</param>
public abstract void Reason(List<ICharacter> targets);
}
开发状态管理类 SoldierFSMSystem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoldierFSMSystem
{
private List<ISoldierState> stateList = new List<ISoldierState>();
private ISoldierState mCurrentState;
public ISoldierState CurrentState { get { return mCurrentState; } }
public void AddState(ISoldierState state)
{
if (state == null)
{
Debug.Log("要