完整工程:https://gitee.com/NKG/DesignPatterns/blob/master/DesignPatterns.unitypackage
首先在Unity下面创建如下文件
首先是场景都要继承的
ISceneState
其中包括了场景的生命周期函数,场景名称,场景控制器的引用。
using System.Collections;
using System.Collections.Generic;
using Scenes.Scripts.StatePattern.RealSample;
using UnityEngine;
public class ISceneState
{
private string m_StateName = "ISceneState";
public string StateName
{
get { return m_StateName; }
set { m_StateName = value; }
}
protected SceneStateController m_Controller = null;
public ISceneState(SceneStateController Controller)
{
m_Controller = Controller;
}
/// <summary>
/// 进入场景时调用的函数
/// </summary>
public virtual void StateBegin()
{
}
/// <summary>
/// 场景结束时调用的函数
/// </summary>
public virtual void StateEnd()
{
}
/// <summary>
/// 场景更新
/// </summary>
public virtual void StateUpdate()
{
}
}
场景控制器
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneStateController
{
private ISceneState m_State;
private bool m_bRunBegin = false;
private AsyncOperation _asyncOperation;
public SceneStateController(){}
public void SetState(ISceneState state, string LoadSceneName)
{
m_bRunBegin = false;
LoadScene(LoadSceneName);
if (m_State != null)
{
m_State.StateEnd();
}
m_State = state;
}
private void LoadScene(string loadSceneName)
{
if (string.IsNullOrEmpty(loadSceneName))
{
return;
}
_asyncOperation = SceneManager.LoadSceneAsync(loadSceneName);
}
public void StateUpdate()
{
//如果上一个场景还没有加载完,那就让他继续加载
if (_asyncOperation!=null)
{
if(!_asyncOperation.isDone)
return;
}
if (m_State != null && m_bRunBegin == false)
{
m_State.StateBegin();
m_bRunBegin = true;
}
if (m_State != null)
{
m_State.StateUpdate();
}
}
}
游戏入口
using System;
using System.Collections;
using System.Collections.Generic;
using Scenes.Scripts.StatePattern.RealSample;
using UnityEngine;
public class GameEntry : MonoBehaviour {
SceneStateController m_SceneStateController=new SceneStateController();
private void Awake()
{
GameObject.DontDestroyOnLoad(this.gameObject);
}
// Use this for initialization
private void Start () {
//设置起始场景
m_SceneStateController.SetState(new StartState(m_SceneStateController),"StartState");
}
// Update is called once per frame
//更新状态
void Update () {
m_SceneStateController.StateUpdate();
}
}
开始场景
using UnityEngine;
public class StartState : ISceneState
{
public StartState(SceneStateController Controller) : base(Controller)
{
this.StateName = "StartState";
}
public override void StateBegin()
{
Debug.Log("进入开始场景");
}
/// <summary>
/// 更换场景
/// </summary>
public override void StateUpdate()
{
//按下鼠标左键来切换场景
if (Input.GetMouseButtonDown(0))
{
m_Controller.SetState(new MainMenuState(m_Controller), "MainMenuState");
}
}
}
菜单场景中我们需要一个按钮来进入战斗,打开菜单场景,新建Button
using UnityEngine;
using UnityEngine.UI;
public class MainMenuState : ISceneState
{
/// <summary>
/// 获取改变场景按钮的引用
/// </summary>
public Button ChangeState;
public MainMenuState(SceneStateController Controller) : base(Controller)
{
this.StateName = "MainMenuState";
}
public override void StateBegin()
{
ChangeState = GameObject.Find("Button").GetComponent<Button>();
ChangeState.onClick.AddListener(ToChangestate);
Debug.Log("进入菜单场景");
}
private void ToChangestate()
{
Debug.Log("开始战斗的按钮被点击,正在切换到战斗场景");
m_Controller.SetState(new BattleState(m_Controller), "BattleState");
}
}
战斗场景
using UnityEngine;
public class BattleState:ISceneState
{
public BattleState(SceneStateController Controller) : base(Controller)
{
this.StateName = "BattleState";
}
public override void StateBegin()
{
Debug.Log("进入战斗场景");
}
public override void StateEnd()
{
Debug.Log("战斗结束,回到菜单场景");
}
public override void StateUpdate()
{
if (Input.GetMouseButtonDown(0))
{
m_Controller.SetState(new MainMenuState(m_Controller),"MainMenuState");
}
}
}
回到Unity,在GameEntry里创建一个空的GameObject,将GameEntry脚本挂载上去。
把这几个场景Build
点击运行