所謂流程,本質是對于狀态機的再封裝。一個遊戲在運作是,不可能全程處于一個狀态,遊戲運作的不同狀态,我稱其為流程,比如剛打開遊戲的時候,可能處在登入頁面,或者說黑屏動畫的時候在加載資源,這就是遊戲運作的兩個不同狀态,這就是流程。
ProcedureBase
流程基類,本質就是一個狀态
/// <summary>
/// 流程基類
/// </summary>
public class ProcedureBase : FsmState<ProcedureManager>
{
public override void OnEnter(Fsm<ProcedureManager> fsm)
{
base.OnEnter(fsm);
Debug.Log("進入流程:" + GetType().FullName);
}
public override void OnLeave(Fsm<ProcedureManager> fsm, bool isShutdown)
{
base.OnLeave(fsm, isShutdown);
Debug.Log("離開流程:" + GetType().FullName);
}
}
ProcedureManager
/// <summary>
/// 流程管理器
/// </summary>
public class ProcedureManager : ManagerBase
{
/// <summary>
/// 狀态機管理器
/// </summary>
private FsmManager m_FsmManager;
/// <summary>
/// 流程的狀态機
/// </summary>
private Fsm<ProcedureManager> m_ProcedureFsm;
/// <summary>
/// 所有流程的清單
/// </summary>
private List<ProcedureBase> m_procedures;
/// <summary>
/// 入口流程
/// </summary>
private ProcedureBase m_EntranceProcedure;
/// <summary>
/// 目前流程
/// </summary>
public ProcedureBase CurrentProcedure
{
get
{
if (m_ProcedureFsm == null)
{
Debug.LogError("流程狀态機為空,無法擷取目前流程");
}
return (ProcedureBase)m_ProcedureFsm.CurrentState;
}
}
public override int Priority
{
get
{
return ManagerPriority.ProcedureManager.GetHashCode();
}
}
public ProcedureManager()
{
m_FsmManager = FrameworkEntry.Instance.GetManager<FsmManager>();
m_ProcedureFsm = null;
m_procedures = new List<ProcedureBase>();
}
public override void Init()
{
}
public override void Shutdown()
{
}
public override void Update(float time)
{
}
}
public class ProcedureManager : ManagerBase
{
/// <summary>
/// 添加流程
/// </summary>
public void AddProcedure(ProcedureBase procedure)
{
if (procedure == null)
{
Debug.LogError("要添加的流程為空");
return;
}
m_procedures.Add(procedure);
}
/// <summary>
/// 設定入口流程
/// </summary>
/// <param name="procedure"></param>
public void SetEntranceProcedure(ProcedureBase procedure)
{
m_EntranceProcedure = procedure;
}
/// <summary>
/// 建立流程狀态機
/// </summary>
public void CreateProceduresFsm()
{
m_ProcedureFsm = m_FsmManager.CreateFsm(this, "", m_procedures.ToArray());
if (m_EntranceProcedure == null)
{
Debug.LogError("入口流程為空,無法開始流程");
return;
}
//開始流程
m_ProcedureFsm.Start(m_EntranceProcedure.GetType());
}
}
// 用這個流程模拟資源加載,3秒後正式進入遊戲流程
public class Procedure_Loading : ProcedureBase
{
private float time = 0;
public override void OnUpdate(Fsm<ProcedureManager> fsm, float time)
{
this.time += time;
if (this.time > 3)
{
ChangeState<Procedure_Gaming>(fsm);
}
}
}
// 這個是遊戲中,當點選滑鼠左鍵時,遊戲切換到暫停狀态
public class Procedure_Gaming : ProcedureBase
{
public override void OnUpdate(Fsm<ProcedureManager> fsm, float time)
{
Debug.Log("遊戲中...");
if (Input.GetMouseButtonDown(0))
{
ChangeState<Procedure_Pause>(fsm);
}
}
}
// 這個是暫停中,當點選滑鼠左鍵時,繼續運作遊戲
public class Procedure_Pause : ProcedureBase
{
public override void OnUpdate(Fsm<ProcedureManager> fsm, float time)
{
Debug.Log("暫停中...");
if (Input.GetMouseButtonDown(0))
{
ChangeState<Procedure_Gaming>(fsm);
}
}
}
public class test : MonoBehaviour
{
void Start()
{
var procedureManager = SGFEntry.Instance.GetManager<ProcedureManager>();
Procedure_Loading loading = new Procedure_Loading();
procedureManager.AddProcedure(loading);
procedureManager.SetEntranceProcedure(loading);
procedureManager.AddProcedure(new Procedure_Gaming());
procedureManager.AddProcedure(new Procedure_Pause());
procedureManager.CreateProceduresFsm();
}
}