我的毕设题目是《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是贯穿游戏运行生命周期的有限状态机,其生命周期:OnInit -> OnEnter -> OnUpdate -> OnLeave -> OnDestroy。且必须要有一个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);
}
}
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);
}
}
}