3.Unity 场景有限状态机(FSM)管理(最详细)

现在用FSM进行游戏场景管理还是比较多,主要是场景的进入退出处理任务和逻辑起比较清晰简单,当然现在一般xlua的hotfix来做热补丁的场景处理也多起来(以便于后期有副本的场景加载更新)。本篇(公司游戏没加场景动态更新前的)只介绍用c#处理的场景管理(后面有时间加一篇动态的更新的场景管理):

 

1.FSM场景管理 代码架构图:

2 代码块搭建说明:

(1)定义 接口Istate。

(2).定义所有场景状态机的父类ScenceState,并且继承接口Istate。

(3).定义条件转换类TransationPipe。

(4).定义录场景LoaginSatae,场景控制器LonginControll,场景显示接口LonginPresenter;主场景MainState......;战斗场景BattleState......。

(5).定义场景管理器SceneStateManger;并且创建登录场景LoaginSatae及相关转出条件;主场景MainState及相关转出条件;战斗场景BattleState及相关转出条件。

(6)定义游戏管理器GameManger,并且创建场景管理器SceneStateManger.调用场景入口。

3 具体代码

(1).接口Istate:

public interface IState 
{
    //场景进入调用方法
	void OnEnter ();
    //场景中轮询调用方法
	void Tick ();
    //场景退出调用方法
	void OnExit();
}

(2).类ScenceState:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;

public class SceneState :IState
{
	/// <summary>
	/// 这个状态的持有者
	/// </summary>
	protected SceneStateManager Owner;

	/// <summary>
	/// 这个状态的名字
	/// </summary>
	public string name;

	private List<TransationPipe> pipelines = new List<TransationPipe>();

	/// <summary>
	/// 关闭无参数的构造函数
	/// </summary>
	private SceneState (){}
    
    //设置状态的持有者(场景管理器)
	public SceneState(string _name , SceneStateManager myOwner)
	{
		name = _name;
		Owner = myOwner;
	}
    
    //场景进入调用方法
	public virtual void OnEnter()
	{
        
	}

	/// <summary>
	/// 转移条件检测
	/// </summary>
	/// <returns>要跳转到哪里去.</returns>
	public string CheckTransation()
	{
		for(int i = 0; i < pipelines.Count; i++)
		{
			if (pipelines [i].condition != null)
			{
				if (pipelines [i].condition ())
				{
					return pipelines [i].target;
				}
			}
		}
		return GameSceneNames.NO_OUPT;
	}

	public virtual void Tick()
	{
		
	}

	public virtual void OnExit()
	{
        Debug.Log(this.name + " :场景退出了");
	}
    
    //添加转移条件
    public void AddPipe(TransationPipe tp)
    {
        if (pipelines.Contains(tp)) Debug.Log("已经有了此条件");
        else
        pipelines.Add(tp);
    }
}

(3).场景转移条件类TransationPipe:

public class TransationPipe
{
	public delegate bool Check();
    
    //获取转出条件的方法
	public Check condition;
    
    //场景转出目的场景的名字
	public string target;

	private TransationPipe(){}

	public TransationPipe(string des , Check _condition)
	{
		target = des;
		condition = _condition;
	}
}

(4.1).登录场景状态机LonginState:

using UnityEngine;
using System.Collections;

public class LonginState : SceneState
{
	public LonginState (string name, SceneStateManager manager) : base (name ,manager){ }
    //场景需求的UI和模型对象引用(最好动态加载)
	LoginPresenter presenter;
   
   
    //场景进入调用
	public override void OnEnter ()
	{
        //设置场景条件为退出状态
        SceneCtrl.Instance.isSureExit = true;
       
        presenter = GameObject.Find("Canvas").GetComponent<LoginPresenter>();      
        
        //登录场景中的场景控制器介入
        LoginPanelController.Instance.Initalize (presenter);
    
		          
      //添加相关监听(是否获取地块信息成功)。(mvc)并且在LoginPanelController中处理相关获取的
        信息并且调用Presenter显示
  GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.BlockInfoSuccess, LoginPanelController.Instance.OnGetBlockInfoSuccess);

      //添加相关监听(是否获取地块信息失败)
     GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.BlockInfoFailure, LoginPanelController.Instance.OnGetBlockInfoFailure);

      //添加相关监听(是否获取天气信息成功) 
  GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.WeatherInfoSuccess, LoginPanelController.Instance.OnGetWetherInfoSuccess);

      //添加相关监听(是否获取天气信息失败)   

GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.WeatherInfoFailure, LoginPanelController.Instance.OnGetWetherInfoFailure);

      //添加相关监听(是否获取登录信息成功)登录    

GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.LoginSuccess, LoginPanelController.Instance.OnPlayerLoginSuccess);
        GameManager.Instance.gameEventDispatcher.AddEventListener(GameEventType.LoginFailure, LoginPanelController.Instance.OnPlayerLoginFailure);
        
         //开启音乐

 AudioManager.Instance.PlayBGM("login");
        //退出到主场景的条件开启可设置

 SceneCtrl.Instance.isExitMainScene = false;
      
 GameManager.Instance.socketManager.ExitConectAgin();
        SceneCtrl.Instance.loginSuccess = false;

		//登录场景通知按钮添加监听

   presenter.noticeBtn.onClick.AddListener(LoginPanelController.Instance.OpenNotice);

		GameManager.Instance.gameInstance.RandomEventContainer.Clear ();
	}

	public override void Tick ()
	{
        //计算时间
        LoginPanelController.Instance.TimeTick();
	}
    
     //场景退出
	public override void OnExit ()
	{
        //移除相关监听

GameManager.Instance.gameEventDispatcher.RemoveEventListener (GameEventType.LoginSuccess, LoginPanelController.Instance.OnPlayerLoginSuccess);
GameManager.Instance.gameEventDispatcher.RemoveEventListener (GameEventType.LoginFailure, LoginPanelController.Instance.OnPlayerLoginFailure);
        GameManager.Instance.gameEventDispatcher.RemoveEventListener(GameEventTy
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值