设计模式实战学习笔记(二):模板、有限状态机FSM、角色管理系统

(六)模板模式

模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,是一种基于继承的代码复用技术。

相关链接: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("要
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值