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)
{
}
}