-
本文档参考Demo
gitee地址: https://gitee.com/xiongks/UnityGameFameworkDocDemo
-
下载框架
gitee地址:https://gitee.com/jiangyin/UnityGameFramework
-
参考项目
- 打飞机:https://gitee.com/jiangyin/StarForce/tree/master/Assets
-
搭建框架
-
拖入一个GameFramework的预制体到场景中(这个场景作为启动场景)
-
运行游戏可以看到左上角调试按钮,点开可以看到运行时调试信息
-
报错 > Entrance procedure is invalid. 意思是,入口流程不可用
-
-
流程
-
流程是Ugf的最基本概念,贯穿整个游戏,其本质就是个状态机
-
在GameFramework的Procedure子物体上选择ProcedureExample,并设置未初始流程就不会报错了
-
仿照ProcedureExample自己写一个流程类(继承自ProcedureBase),并设置为初始流程试试吧!
-
流程可以重写 OnEnter(),OnInit(),OnUpdate(),OnLive() 这几个方法
-
切换流程使用 ChangeState( procedureOwner);
-
-
命名空间
using UnityGameFramework;//最好默认引用 using UnityGameFramework.Runtime;//最好默认引用 using GameFramework.Scene;//需要用到的模块scene只是其中的场景模块 using GameFramework.Procedure;//需要用到的模块Procedure只是其中的流程模块 using GameFramework.Fsm;//需要用到的模块Fsm只是其中的状态机模块
-
如何获取组件
-
我们可以看到GameFramework这个物体下面有很多个子物体,每个物体都是模块(作者把他们称为组件)
-
使用GameEntry.GetComponent();获取相应的模块(以后我们也成为组件吧)
-
现在不用关心组件怎么使用(步子迈大了容易扯着蛋)
-
-
SceneComponent 操作场景
- 加载场景
using GameFramework.Fsm; using GameFramework.Procedure; using UnityGameFramework.Runtime; public class TestSceneProcedue : ProcedureBase { protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); //加载场景 GameEntry.GetComponent<SceneComponent>(). LoadScene("Assets/Study/Scene_Play.unity"); } }
- 卸载场景(不会卸载初始场景,因为初始场景是用来放框架的)
GameEntry.GetComponent<SceneComponent>(). UnloadScene("Assets/Study/Scene_Play.unity");
注意:Ugf中所有资源引用均使用项目文件夹下的相对路径从Assets开始的.以后UI,声音,预制体都这样引用,在资源上右键点击 copy path 选项可以复制资源路径
-
事件机制
- 下面的代码演示如何相应场景加载成功的事件
using GameFramework.Event; using GameFramework.Fsm; using GameFramework.Procedure; using UnityGameFramework.Runtime; //记得把这个测试流程设置为初始流程 public class TestEventProcedue : ProcedureBase { protected override void OnInit(IFsm<IProcedureManager> procedureOwner) { base.OnInit(procedureOwner); GameEntry.GetComponent<EventComponent>(). Subscribe(LoadSceneSuccessEventArgs.EventId, LoadSceneSuccessHandle); //注册事件 GameEntry.GetComponent<SceneComponent>(). LoadScene("Assets/Study/Scene_Play.unity"); } //事件响应的方法 private void LoadSceneSuccessHandle(object sender, GameEventArgs e) { //需要把事件参数转换为具体事件参数才能拿到相关信息 LoadSceneSuccessEventArgs arg = e as LoadSceneSuccessEventArgs; Log.Debug("响应事件-"+"成功加载场景"+arg.SceneAssetName); } }
ugf内置了很多事件:
每个事件参数类有一个唯一的静态的EventId属性,注册事件需要用到
CloseUIFormCompleteEventArgs DownloadFailureEventArgs 下载失败 DownloadStartEventArgs 开始下载 DownloadSuccessEventArgs 下载成功 DownloadUpdateEventArgs HideEntityCompleteEventArgs 隐藏实体完成 LoadConfigDependencyAssetEventArgs LoadConfigFailureEventArgs 记载配置失败 LoadConfigSuccessEventArgs 加载配置成功 LoadConfigUpdateEventArgs 加载配置更新 LoadDataTableDependencyAssetEventArgs LoadDataTableFailureEventArgs 加载数据表失败 LoadDataTableSuccessEventArgs 加载数据表成功 LoadDataTableUpdateEventArgs 加载数据表更新 LoadDictionaryDependencyAssetEventArgs LoadDictionaryFailureEventArgs LoadDictionarySuccessEventArgs LoadDictionaryUpdateEventArgs LoadSceneDependencyAssetEventArgs LoadSceneFailureEventArgs 加载场景失败 LoadSceneSuccessEventArgs 加载场景成功 LoadSceneUpdateEventArgs 加载场景更新 NetworkClosedEventArgs 网络关闭 NetworkConnectedEventArgs 网络已连接 NetworkCustomErrorEventArgs 网络用户错误 NetworkErrorEventArgs 网络错误 NetworkMissHeartBeatEventArgs OpenUIFormDependencyAssetEventArgs OpenUIFormFailureEventArgs UI窗口打开失败 OpenUIFormSuccessEventArgs UI窗口打开成功 OpenUIFormUpdateEventArgs UI窗口打开更新 PlaySoundDependencyAssetEventArgs PlaySoundFailureEventArgs 播放声音成功 PlaySoundSuccessEventArgs 播放声音失败 PlaySoundUpdateEventArgs 播放声音更新 ResourceUpdateChangedEventArgs 资源更新改变 ResourceUpdateFailureEventArgs 资源更新失败 ResourceUpdateStartEventArgs 资源更新开始 ResourceUpdateSuccessEventArgs 资源更新成功 ShowEntityDependencyAssetEventArgs ShowEntityFailureEventArgs 显示实体失败 ShowEntitySuccessEventArgs 显示实体成功 ShowEntityUpdateEventArgs 显示实体更新 UnloadSceneFailureEventArgs 更新场景失败 UnloadSceneSuccessEventArgs 更新场景成功 WebRequestFailureEventArgs 网络请求失败 WebRequestStartEventArgs 网络请求开始 WebRequestSuccessEventArgs 网络请求成功 -
UIComponent 管理UI
- 先找到框架物体下UI子物体(模块)上的UI组件添加一个Test组
- 创建一个Canvas包含一个Button子物体,把Canvas改名为TestUI,做成预制体(TestUI)
- 编写一个TestUIFormLogic脚本继承自UIFormLogic类,并挂到TestUI预制体上(重要)
- 使用代码加载TestUI窗体
using GameFramework.Fsm; using GameFramework.Procedure; using UnityGameFramework.Runtime; public class TestUIProcedue : ProcedureBase { protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); //加载TestUI GameEntry.GetComponent<UIComponent>(). OpenUIForm("Assets/Study/UI/TestUI.prefab", "Test");//Test是分组名称 } }
注意上面第3步不能没有否则会报错:
UI form ‘Assets/Study/UI/TestUI.prefab’ can not get UI form logic.
Test分组的作用是控制显示顺序,根据需要取名字
- 我们可以重写TestUIFormLogic中以On开头的方法添加自己的UI窗口控制逻辑
-
声音播放
- 先找到框架物体下Sound子物体(模块)上的Sound组件添加一个group1组
- Sound组件的Agent Helper Count 属性设置一个>1的值
using GameFramework.Fsm; using GameFramework.Procedure; using UnityGameFramework.Runtime; public class TestSoundProcedure : ProcedureBase { protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); //播放声音 GameEntry.GetComponent<SoundComponent>(). PlaySound("Assets/Study/Sound/cloth.ogg","group1"); } }
- PlaySound()方法有很多个重载,可以指定声音的播放位置
-
创建实体
- 先找到框架物体下Entity上的Entity组件添加一个group1组
- group1的各项参数设置为60,具体每项数值的作用大家去查下词典,或官方文档
- 先创建一个Bullet预制体,编写一个BulletEntity类继承自EntityLogic,重写OnShow方法随便写点啥
using GameFramework.Fsm; using GameFramework.Procedure; using UnityEngine; using UnityGameFramework.Runtime; public class TestEntityProcedure : ProcedureBase { EntityComponent entityComp; protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); entityComp = GameEntry.GetComponent<EntityComponent>(); } protected override void OnUpdate ( IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds) { //显示实体 if (Input.GetKeyDown(KeyCode.A)) { entityComp.ShowEntity<BulletEntity> (1, "Assets/Study/Entity/BulletEntity.prefab", "group1"); } //隐藏实体 if (Input.GetKeyDown(KeyCode.B)) { entityComp.HideEntity(entityComp.GetEntity(1)); } } }
-
Reference Pool
-
Object Pool
-
数据表
- 先准备一个’\t’数据表txt文件,这个可以用Excel来制作,并导出,这里我们使用手写内容如下:
# 学生表 # id name age # int string int # id name age 1 张三 15 2 lisi 20
上面的表1234行以#开头为注释,多一行少一行都可以,程序不会读取.此文件需要保存为utf8编码 导出Excle表为上述txt文档需要手动写个工具来实现,否则很难导出utf8编码的
-
编写数据表每一行数据对应的类
using GameFramework; using UnityGameFramework.Runtime;//最好默认引用 public class StudentDataRow : DataRowBase { private int id; public string name; public int age; public override int Id => id; public override bool ParseDataRow(GameFrameworkSegment<string> dataRowSegment) { //这里有点坑人,看仔细!!! string allText = dataRowSegment.Source;//获取所有文本 //截取一行后offset会自增 string line = allText.Substring(dataRowSegment.Offset, dataRowSegment.Length); string[] arr = line.Split('\t');//分割 int colum = 0; colum++;//跳过#号列,需要跳过其他列也可以再下面的代码中写++ id = int.Parse(arr[colum++]); name = arr[colum++]; age = int.Parse(arr[colum++]); return true; } }
3.编写一个流程类,并设置为初始流程来测试加载
using GameFramework; using GameFramework.DataTable; using GameFramework.Event; using GameFramework.Fsm;//需要用到的模块Fsm只是其中的状态机模块 using GameFramework.Procedure;//需要用到的模块Procedure只是其中的流程模块 using UnityGameFramework.Runtime;//最好默认引用 using LoadDataTableSuccessEventArgs = UnityGameFramework.Runtime.LoadDataTableSuccessEventArgs; public class TestDatatableProcedure : ProcedureBase { DataTableComponent tableComponent; EventComponent eventComponent; protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); tableComponent = GameEntry.GetComponent<DataTableComponent>(); eventComponent = GameEntry.GetComponent<EventComponent>(); //注册当表格加载成功的事件 eventComponent.Subscribe(LoadDataTableSuccessEventArgs.EventId,ff); //开始加载,ugf默认所有加载都是异步加载,需要先注册事件相应加载成功后的逻辑 tableComponent.LoadDataTable<StudentDataRow> ("Student", "Assets/Study/DataTable/Student.txt", LoadType.Text); } //数据表加载成功后会相应这个方法 private void ff(object sender, GameEventArgs e) { var LoadDataTableSuccessEventArgs = e as LoadDataTableSuccessEventArgs; string dataTableName= LoadDataTableSuccessEventArgs.DataTableName; var StudentTable= tableComponent.GetDataTable(typeof(StudentDataRow)) as IDataTable< StudentDataRow>; string name= StudentTable.GetDataRow(1).name; Log.Debug(name); } }
-
网络请求
-
下载
-
网络频道
-
本地化
-
设置
-
资源打包
-
资源更新