遊戲開發中的設計模式——狀態模式
阿新 • • 發佈:2019-01-14
Siki學院——遊戲開發中的設計模式
狀態模式—— 菜鳥篇個人學習筆記
案例開發——應用於場景轉換
由StartState場景,自動跳轉到MainMenuState場景,點選按鈕後,跳轉到BattleState場景
GameLoop
採用了指令碼和遊戲物體分離的開發模式
using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSystems; public class GameLoop : MonoBehaviour { private SceneStateControl controller = null; void Awake() { DontDestroyOnLoad(this.gameObject); } void Start () { controller = new SceneStateControl(); controller.SetState(new StartState(controller),false);//設定預設狀態 為開始狀態,不需要載入場景 } void Update () { controller.StateUpdate(); } }
SceneStateControl
using System; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.SceneManagement; public class SceneStateControl { private ISceneState mState; private AsyncOperation mAO; private bool mIsRunStart = false; /// <summary> /// 設定狀態(場景) /// </summary> /// <param name="state"></要設定的狀態,即卻換到那個狀態> /// <param name="isLoadScene"></增加判斷是否需要載入場景> public void SetState(ISceneState state,bool isLoadScene=true) //增加判斷是否需要載入場景 { if(mState!=null) { mState.StateEnd();//讓上一個場景做一下清理工作 } mState = state; //設定新狀態 if(isLoadScene) { mAO = SceneManager.LoadSceneAsync(mState.SceneName);//非同步載入,返回一個AsyncOperation //mState.StateStart();//若LoadScene直接寫在這裡,可能出現場景還沒載入完成,就執行了例如夾雜元件之類的操作,會出現問題 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(); //執行進入狀態方法 mIsRunStart = true; } if (mState!=null) { mState.StateUpdate(); } } }
ISceneState
using System; using System.Collections.Generic; using System.Text; using UnityEngine; public class ISceneState { private string mSceneName; protected SceneStateControl mControler; public ISceneState(string sceneName, SceneStateControl controller) { mSceneName = sceneName; mControler = controller; } public string SceneName { get { return mSceneName; } } public virtual void StateStart() { }//進入狀態時--例:得到場景中的元件 public virtual void StateEnd() { }//離開狀態時--例:銷燬遊戲物體 public virtual void StateUpdate() { }//狀態中的操作 }
具體狀態(StartState、MainState、AttackState)
StartState
using UnityEngine.UI;
using UnityEngine;
public class StartState:ISceneState
{
public StartState(SceneStateControl controller): base("01StartScene",controller)
{
}
private Image mLogo;
private int mSmothTime=1;
private float mWaitTime = 2;
public override void StateStart()
{
mLogo = GameObject.Find("BG").GetComponent<Image>();
mLogo.color = Color.black;
}
public override void StateUpdate()
{
mLogo.color = Color.Lerp(mLogo.color,Color.white,mSmothTime*Time.deltaTime);
mWaitTime -= Time.deltaTime;
if (mWaitTime<=0)
{
mControler.SetState(new MainState(mControler));
}
}
}
MainState
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
public class MainState:ISceneState
{
public MainState(SceneStateControl controller): base("02MainScene", controller)
{
}
public override void StateStart()
{
GameObject.Find("StartButton").GetComponent<Button>().onClick.AddListener(OnStartBtnClick);
}
private void OnStartBtnClick()
{
mControler.SetState(new AttackState(mControler));
}
}
AttackState
using System;
using System.Collections.Generic;
using System.Text;
public class AttackState:ISceneState
{
public AttackState(SceneStateControl controller): base("03AttackScene", controller)
{
}
}