【UGF】(一)Procedure、Event的使用及DataTable的创建与读取

我的毕设题目是《MOBA游戏<战地王者>的设计与开发》,相对之前开发过的一些小游戏,这个项目涉及的模块和逻辑过于复杂,需要一个完善的游戏框架管理游戏逻辑和资源,在github上找到两个不错的开源Unity游戏框架uFrame和GameFramework,但是uFrame似乎很久没有更新,最终选择了GameFramework进行学习。

GameFramework相关介绍:http://gameframework.cn/

Unity Game Framework插件下载:https://github.com/EllanJiang/UnityGameFramework/releases

博文基于环境:UnityGameFramework 3.1.0 && Unity 2017.3.0f3

导入UGF插件后在框架目录下有个GameFramework Prefab,这个Prefab中已经集成了UGF的17个功能模块组件,按照Manager Of Managers的思想,定义一个UGF类,通过此类访问所有功能模块的实例以方便使用。

UGF.cs:

using UnityEngine;
namespace UnityGameFramework.Runtime
{
    public class UGF : MonoBehaviour
    {
        public static BaseComponent Base { get; private set; }
        public static DataNodeComponent DataNode { get; private set; }
        public static DataTableComponent DataTable { get; private set; }
        public static DebuggerComponent Debugger { get; private set; }
        public static DownloadComponent Download { get; private set; }
        public static EntityComponent Entity { get; private set; }
        public static EventComponent Event { get; private set; }
        public static FsmComponent Fsm { get; private set; }
        public static LocalizationComponent Localization { get; private set; }
        public static NetworkComponent Network { get; private set; }
        public static ObjectPoolComponent ObjectPool { get; private set; }
        public static ProcedureComponent Procedure { get; private set; }
        public static ResourceComponent Resource { get; private set; }
        public static SceneComponent Scene { get; private set; }
        public static SettingComponent Setting { get; private set; }
        public static SoundComponent Sound { get; private set; }
        public static UIComponent UI { get; private set; }
        public static WebRequestComponent WebRequest { get; private set; }
        private void Start()
        {
            UGF.Base = GameEntry.GetComponent();
            UGF.DataNode = GameEntry.GetComponent();
            UGF.DataTable = GameEntry.GetComponent();
            UGF.Debugger = GameEntry.GetComponent();
            UGF.Download = GameEntry.GetComponent();
            UGF.Entity = GameEntry.GetComponent();
            UGF.Event = GameEntry.GetComponent();
            UGF.Fsm = GameEntry.GetComponent();
            UGF.Localization = GameEntry.GetComponent();
            UGF.Network = GameEntry.GetComponent();
            UGF.ObjectPool = GameEntry.GetComponent();
            UGF.Procedure = GameEntry.GetComponent();
            UGF.Resource = GameEntry.GetComponent();
            UGF.Scene = GameEntry.GetComponent();
            UGF.Setting = GameEntry.GetComponent();
            UGF.Sound = GameEntry.GetComponent();
            UGF.UI = GameEntry.GetComponent();
            UGF.WebRequest = GameEntry.GetComponent();
        }
    }
}

一、Procedure的使用

Procedure是贯穿游戏运行生命周期的有限状态机,其生命周期:OnInit -> OnEnter -> OnUpdate -> OnLeave -> OnDestroy。且必须要有一个Procedure作为启动入口。使用Procedure可以清晰的管理游戏逻辑,使界面和逻辑分离。

①自定义Procedure

需要继承GameFramework.Procedure.ProcedureBase,Procedure Component会列出所有可用Procedure,勾选表示流程可用,可以通过ChangeState函数切换。如图:

using GameFramework.Fsm;
using GameFramework.Procedure;
using UnityGameFramework.Runtime;
using GameFramework.Event;

    public class LaunchProcedure : ProcedureBase
    {
        protected override void OnEnter(IFsm procedureOwner)
        {
            base.OnEnter(procedureOwner);ChangeState(procedureOwner);
        }
    }

【UGF】(一)Procedure、Event的使用及DataTable的创建与读取_第1张图片

②切换Procedure

切换流程:
void ChangeState(IFsm fsm) where TState : FsmState;
void ChangeState(IFsm fsm, Type stateType);

二、DataTable的创建与读取

将游戏数据以表格的形式保存成文件后,使用DataTable模块读取并解析游戏数据。

1.DataTable数据表的创建

①使用Excel创建/编辑数据表

#表示注释,框架读取数据表时会跳过#开头的行,数据表格式可自定义,框架只负责逐行读取数据传递过来,然后由用户对每行数据进行格式解析。
【UGF】(一)Procedure、Event的使用及DataTable的创建与读取_第2张图片

②编辑好数据表后点击另存为以制表符分隔的方式保存为文本文件

【UGF】(一)Procedure、Event的使用及DataTable的创建与读取_第3张图片

③更改数据表的编码方式为UTF-8

Excel另存为文本文件后默认是ANSI编码方式,一旦数据表中包含中文字符在Unity2017中就无法读取文件数据。
【UGF】(一)Procedure、Event的使用及DataTable的创建与读取_第4张图片

2.DataTable数据表的读取

读取数据表需要新建一个类并 实现 GameFramework.DataTable. IDataRow接口, 用于存放解析后的表数据。其中Id是表数据必须要有的变量,用于查找数据(GetDataRow(Id)),Id相当于数据库中的主键,不允许存在相同Id。ParseDataRow(string dataRowText)是IDataRow接口的成员函数,dataRowText是由框架逐行传递进来的数据表数据,需要用户在代码中解析。
按照上面表数据的格式解析代码如下:
using GameFramework.DataTable;
public class PlayerData : IDataRow
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public void ParseDataRow(string dataRowText)
    {
        var strArr = dataRowText.Split('\t');//把每行数据以制表符分隔为字符串数组
        int index = 1;//跳过被注释占用的第一列
        Id = int.Parse(strArr[index++]);
        Name = strArr[index];
    }
}
读取表数据:

using GameFramework.Fsm;
using GameFramework.Procedure;
using UnityGameFramework.Runtime;
using GameFramework.Event;
    public class LaunchProcedure : ProcedureBase
    {
        private bool isLoadSceneSuccess = false;
        protected override void OnEnter(IFsm procedureOwner)
        {
            base.OnEnter(procedureOwner);
            if (!UGF.DataTable.HasDataTable("PlayerDataTable"))
            {
                UGF.Event.Subscribe(LoadDataTableSuccessEventArgs.EventId, OnLoadDataTableSuccess);
                UGF.DataTable.LoadDataTable("PlayerDataTable", "Assets/GameMain/DataTables/PlayerData.txt");
            }
            else
            {
                PrintPlayerData();
            }
        }
        private void OnLoadDataTableSuccess(object sender, GameEventArgs e)
        {
            PrintPlayerData();
        }
        private void PrintPlayerData()
        {
            var dt = UGF.DataTable.GetDataTable();
            var playerDataArr = dt.GetAllDataRows();
            foreach (var item in playerDataArr)
            {
                GameFramework.Log.Info("ID:{0},Name:{1}", item.Id, item.Name);
            }
        }
    }

三、Event的使用

上面代码中又涉及到新的模块——Event,Event是框架的事件分发机制,由于框架的加载方式是异步加载,所以需要在数据加载完成后回调一个加载成功的函数,在此函数中进行数据的使用。
通过Event.Subscribe(EventId,Callback);分发事件,
通过Event.Unsubscribe(EventId, Callback)解除事件。

你可能感兴趣的:(Unity游戏框架)