设计模式篇:状态模式(二)

完整工程: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

点击运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值