- 学习网址:http://www.cnblogs.com/wangjq/archive/2012/07/16/2593485.html
原型的实现:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DM01Sate : MonoBehaviour { void Start() { Context context = new Context(); //状态拥有着初始化 context.SetState(new ConcreteStateA(context)); //设置当前的状态,并设置状态的context context.Handle(5); context.Handle(20); context.Handle(30); context.Handle(4); context.Handle(6); } } //Context:状态的拥有者 public class Context { private IState mState; //设置context当前的状态 public void SetState(IState state) { mState = state; } //调用context当前的状态的处理方法 public void Handle(int arg) { mState.Handle(arg); } } public interface IState { void Handle(int arg); //处理当前状态的行为,放在IState里面,子类重写以实现不同的状态对应不同的行为 } public class ConcreteStateA : IState { private Context mContext; //构造函数初始化时设置context public ConcreteStateA(Context context) { mContext = context; } public void Handle(int arg) { Debug.Log("ConcreateStateA.Handle " + arg); if (arg > 10) { mContext.SetState(new ConcreteStateB(mContext)); //转换状态,因此需要拥有context } } } public class ConcreteStateB : IState { private Context mContext; public ConcreteStateB(Context context) { mContext = context; } public void Handle(int arg) { Debug.Log("ConcreateStateB.Handle " + arg); if (arg <= 10) { mContext.SetState(new ConcreteStateA(mContext)); } } }
应用实例:根据状态切换场景
UML类图:
GameLoop类:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameLoop : MonoBehaviour { private SceneStateController controller = null; //持有SceneStateController 类 void Awake() { DontDestroyOnLoad(this.gameObject); } // Use this for initialization void Start () { controller = new SceneStateController(); controller.SetState(new StartState(controller),false); //设置初始化 } // Update is called once per frame void Update () { if(controller!=null) controller.StateUpdate(); //会调用当前状态的更新方法 } }ISceneState类:
using System; using System.Collections.Generic; using System.Text; /// <summary> /// 状态父类 /// </summary> public class ISceneState { private string mSceneName; //场景的名字,根据名字来切换 protected SceneStateController mController;//状态的拥有者 public ISceneState(string sceneName,SceneStateController controller) { mSceneName = sceneName; mController = controller; } public string SceneName { get { return mSceneName; } } //每次进入到这个状态的时候调用,子类重写 public virtual void StateStart() { } public virtual void StateEnd() { } public virtual void StateUpdate(){} }SceneStateController类(状态持有类):
using System; using System.Collections.Generic; using System.Text; using UnityEngine.SceneManagement; using UnityEngine; public class SceneStateController //场景状态管理者,相当于Context { private ISceneState mState; //持有状态 private AsyncOperation mAO; //异步加载的返回值 private bool mIsRunStart = false; //是否运行过StateStart方法 public void SetState(ISceneState state,bool isLoadScene=true) //isLoadScene是否需要加载场景,默认是需要的.这个参数是由于初始场景是不需要加载场景的 { if (mState != null) { mState.StateEnd();//让上一个场景状态做一下清理工作 } mState = state; //设置成新的状态 if (isLoadScene) { mAO = SceneManager.LoadSceneAsync(mState.SceneName);//异步加载场景,后面不能立马执行StateStart方法,因为场景有可能还没有加载成功 mIsRunStart = false; } else { mState.StateStart(); mIsRunStart = true; } } public void StateUpdate() { if (mAO != null && mAO.isDone == false) return; //判断当前是否还在异步加载场景 if (mIsRunStart==false && mAO != null && mAO.isDone == true) { mState.StateStart(); //场景加载完成调用StateStart方法 mIsRunStart = true; //控制只需要调用一次 } //当前状态不为空 调用更新 if (mState != null) { mState.StateUpdate(); } } }
StartState类(开始场景类):
using System; using System.Collections.Generic; using System.Text; using UnityEngine.UI; using UnityEngine; public class StartState:ISceneState //开始场景类 { //构造方法 public StartState(SceneStateController controller):base("01StartScene",controller) { } private Image mLogo; private float mSmoothingSpeed = 1; private float mWaitTime = 2; //动画的时间 public override void StateStart() { //显示Logo mLogo = GameObject.Find("Logo").GetComponent<Image>(); mLogo.color = Color.black; } public override void StateUpdate() { mLogo.color = Color.Lerp(mLogo.color, Color.white, mSmoothingSpeed * Time.deltaTime); //Logo的动画 mWaitTime -= Time.deltaTime; if (mWaitTime <= 0) { mController.SetState(new MainMenuState(mController)); //状态跳转 } } }MainMenuState类(菜单场景):
using System; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.UI; public class MainMenuState:ISceneState { public MainMenuState(SceneStateController controller) : base("02MainMenuScene", controller) { } public override void StateStart() { GameObject.Find("StartButton").GetComponent<Button>().onClick.AddListener(OnStartButtonClick);//按钮注册事件 } private void OnStartButtonClick() { mController.SetState(new BattleState(mController)); //切换到战斗场景 } }BattleState类(战斗场景):
using System; using System.Collections.Generic; using System.Text; public class BattleState:ISceneState { public BattleState(SceneStateController controller):base("03BattleScene",controller) {} //兵营 关卡 角色管理 行动力 成就系统。。。 public override void StateStart() { GameFacade.Insance.Init(); } public override void StateEnd() { GameFacade.Insance.Release(); } public override void StateUpdate() { if (GameFacade.Insance.isGameOver) { mController.SetState(new MainMenuState(mController)); } GameFacade.Insance.Update(); } }