diff --git a/Books/0-介绍.md b/Books/0-介绍.md new file mode 100644 index 00000000..cf03422a --- /dev/null +++ b/Books/0-介绍.md @@ -0,0 +1,29 @@ +# 介绍- Introduce + +### TEngine + + status + + + license + + + last + + + issue + + + topLanguage + + +TEngine是一套用于Unity框架解决方案,用于帮助研发团队快速进行开发。 + +### 开箱即用 +开箱即用、用法简洁,即用即上手.高可读性和详细的文档说明帮助你更快更好的进行游戏开发。您不需要关心框架的底层,分离独自实现您的GamePlay。 + +### 性能强大 +TEngine 底层使用多线程管理与线程间的通信以及事件分发,可插件定制化,把复杂游戏简单化切以高性能、低耦合度实现。 + +### 高内聚低耦合 +内嵌了The Best 次时代热更新解决方案HybridCLR、百万DAU验证的资源解决方案YooAsset diff --git a/Books/1-快速开始.md b/Books/1-快速开始.md new file mode 100644 index 00000000..ac15d86e --- /dev/null +++ b/Books/1-快速开始.md @@ -0,0 +1,58 @@ +# 快速开始- Quickly Start +快速上手 +本教程引导从空项目开始体验TEngine。出于简化起见,只演示目标平台为Windows的情况。 + +请在Standalone平台上正确跑通热更新流程后再自行尝试Android、iOS平台的热更新,它们的流程非常相似。 + +### 1.使用Unity2021.3.20f1c1打开项目工程。 + +### 2.默认选择顶部栏目EditorMode编辑器下的模拟模式并点击Launcher开始运行 +![image](src/1-1.png) + +### 3.Editor编辑器下运行成功! +![image](src/1-2.png) + +### 4.打包运行 + 1.运行菜单 HybridCLR/Define Symbols/Enable HybridCLR 运行开启HybridCLR热更新 + 2.运行菜单 HybridCLR/Generate/All 进行必要的生成操作。这一步不可遗漏!!! + 3.运行菜单 HybridCLR/Build/BuildAssets And CopyTo AssemblyPath,生成热更新dll并copy到热更程序集中。 + 4.运行菜单 YooAsset/AssetBundle Builder 构建AB!!! + 5.打开Build Settings对话框,点击Build And Run,打包并且运行热更新示例工程。 + +### 遇到问题请查看HybridlCLR的常见错误(commonerrors) + +### 系统需求 +默认版本:Unity2021.3.20f1c1 + +支持版本: Unity2019.4 & Unity2020.3 & Unity2021.3 & Unity2022.3 + +支持平台: Windows、OSX、Android、iOS、WebGL + +开发环境: .NET4.x + +### 目录结构 +``` +Assets +├── AssetRaw 资源目录 +├── Atlas 图集目录 +├── GameScripts 热更程序集目录 +├── Scenes 主场景目录 +└── TEngine + ├── AssetSetting YooAsset资源设置 + ├── Editor TEngine-Editor程序集 + └── Runtime TEngine-Runtime程序集 +``` + +### 热更新程序集划分 +``` +Assets/GameScripts +├── Editor 编辑器程序集 +├── HotFix 游戏热更程序集目录 [Folder] +| ├── GameBase 游戏基础框架程序集 [Dll] +| ├── GameProto 游戏配置协议程序集 [Dll] +| ├── BattleCore 游戏核心战斗程序集 [Dll] +| └── GameLogic 游戏业务逻辑程序集 [Dll] +| ├── GameApp.cs 热更主入口 +| └── GameApp_RegisterSystem.cs 热更主入口注册系统 +└── Runtime Runtime程序集 +``` \ No newline at end of file diff --git a/Books/2-框架概览.md b/Books/2-框架概览.md new file mode 100644 index 00000000..bace9642 --- /dev/null +++ b/Books/2-框架概览.md @@ -0,0 +1,67 @@ +# TEngine + +## TEngine-Runtime +### AOT内核基于Gameframework,最简化以及商业化适配。 +![image](src/2-1.png) + +## AOT游戏框架模块基类。 +#### 框架思路为面向接口编程,如Resource资源模块,开发白皮书为先定义IResourceManager的接口规范,然后编写ResourceManager继承框架具体实现(GameFrameworkModule)以及实现接口。最后实现调用层GameFrameworkModuleBase,调用层可以拓展编辑器供开发者自定义模块参数。 +``` csharp +/// +/// 游戏框架模块抽象类。GameFrameworkModule为具体框架模块实现。 +/// +internal abstract class GameFrameworkModule +{ + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal virtual int Priority => 0; + + /// + /// 游戏框架模块轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理游戏框架模块。 + /// + internal abstract void Shutdown(); +} + +//=====================================================================// + +/// +/// 游戏框架模块抽象类。GameFrameworkModuleBase 为Mono调用层。 +/// +public abstract class GameFrameworkModuleBase : MonoBehaviour +{ + /// + /// 游戏框架模块初始化。 + /// + protected virtual void Awake() + { + GameEntry.RegisterModule(this); + } +} +``` + +## 常用模块接口 + +[3-1-资源模块](./3-1-资源模块.md) + +[3-2-事件模块](./3-2-事件模块.md) + +[3-3-内存池模块](./3-3-内存池模块.md) + +[3-4-对象池模块](./3-4-对象池模块.md) + +[3-5-UI模块](./3-5-UI模块.md) + +[3-6-配置表模块](./3-6-配置表模块.md) + +[3-7-流程模块](./3-7-流程模块.md) + +[3-8-网络模块](./3-8-网络模块.md) diff --git a/Books/3-1-资源模块.md b/Books/3-1-资源模块.md new file mode 100644 index 00000000..f72968ed --- /dev/null +++ b/Books/3-1-资源模块.md @@ -0,0 +1,164 @@ +## 3-1.资源模块 - ResourceModule +资源模块运行模式有EditorSimulateMode、OfflinePlayMode以及HostPlayMode +编辑器模式下以顶部导航栏的选项卡为优先选项,打包后以Scene场景中ResourceModule脚本的Enum选项卡为优先选项(打包后不会走EditorSimulateMode) +``` csharp +/// +/// 获取当前资源包版本。 +/// +/// 资源包版本。 +public string GetPackageVersion(); + +/// +/// 异步更新最新包的版本。 +/// +/// 请求URL是否需要带时间戳。 +/// 超时时间。 +/// 请求远端包裹的最新版本操作句柄。 +public UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks = false, int timeout = 60); + +/// +/// 向网络端请求并更新清单 +/// +/// 更新的包裹版本 +/// 更新成功后自动保存版本号,作为下次初始化的版本。 +/// 超时时间(默认值:60秒) +public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60); + +/// +/// 创建资源下载器,用于下载当前资源版本所有的资源包文件。 +/// +public ResourceDownloaderOperation CreateResourceDownloader(); + + +/// +/// 清理包裹未使用的缓存文件。 +/// +public ClearUnusedCacheFilesOperation ClearUnusedCacheFilesAsync(); + + +/// +/// 清理沙盒路径。 +/// +public void ClearSandbox(); + +/// +/// 强制执行释放未被使用的资源。 +/// +/// 是否使用垃圾回收。 +public void ForceUnloadUnusedAssets(bool performGCCollect); + +/// +/// 检查资源是否存在。 +/// +/// 要检查资源的名称。 +/// 检查资源是否存在的结果。 +public HasAssetResult HasAsset(string assetName); + +/// 同步加载资源。 +/// +/// 要加载资源的名称。 +/// 要加载资源的类型。 +/// 资源实例。 +T LoadAsset(string assetName) where T : Object; + +/// +/// 同步加载资源。 +/// +/// 要加载资源的名称。 +/// 父节点位置。 +/// 要加载资源的类型。 +/// 资源实例。 +T LoadAsset(string assetName, Transform parent) where T :Object; + +/// +/// 同步加载资源。 +/// +/// 资源操作句柄。 +/// 要加载资源的名称。 +/// 要加载资源的类型。 +/// 资源实例。 +T LoadAsset(string assetName,out AssetOperationHandle handle) where T : Object; + +/// +/// 同步加载资源。 +/// +/// 要加载资源的名称。 +/// 资源操作句柄。 +/// 父节点位置。 +/// 要加载资源的类型。 +/// 资源实例。 +T LoadAsset(string assetName, Transform parent,out AssetOperationHandle handle) where T :Object; + +/// +/// 异步加载资源。 +/// +/// 要加载资源的名称。 +/// 取消操作Token。 +/// 要加载资源的类型。 +/// 异步资源实例。 +UniTask LoadAssetAsync(string assetName,CancellationToken cancellationToken) where T : Object; + +/// +/// 异步加载游戏物体。 +/// +/// 要加载的游戏物体名称。 +/// 取消操作Token。 +/// 异步游戏物体实例。 +UniTask LoadGameObjectAsync(string assetName,CancellationToken cancellationToken); + +/// +/// 同步加载资源并获取句柄。 +/// +/// 要加载资源的名称。 +/// 要加载资源的类型。 +/// 同步加载资源句柄。 +AssetOperationHandle LoadAssetGetOperation(string assetName) where T : Object; + +/// +/// 异步加载资源并获取句柄。 +/// +/// 要加载资源的名称。 +/// 要加载资源的类型。 +/// 异步加载资源句柄。 +AssetOperationHandle LoadAssetAsyncHandle(string assetName) where T : Object; + +/// +/// 同步加载子资源对象 +/// +/// 资源类型 +/// 资源的定位地址 +public SubAssetsOperationHandle LoadSubAssetsSync(string location) where TObject : UnityEngine.Object; + +/// +/// 异步加载子资源对象 +/// +/// 资源类型 +/// 资源的定位地址 +public SubAssetsOperationHandle LoadSubAssetsAsync(string location) where TObject : UnityEngine.Object; + +/// +/// 同步加载子资源对象 +/// +/// 资源信息。 +public SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo); + +/// +/// 异步加载场景。 +/// +/// 场景的定位地址 +/// 场景加载模式 +/// 加载完毕时是否主动激活 +/// 优先级 +/// 异步加载场景句柄。 +SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100); + +/// +/// 异步加载场景 +/// +/// 场景的资源信息 +/// 场景加载模式 +/// 加载完毕时是否主动激活 +/// 优先级 +/// 异步加载场景句柄。 +SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100); +``` \ No newline at end of file diff --git a/Books/3-2-事件模块.md b/Books/3-2-事件模块.md new file mode 100644 index 00000000..e3a318d9 --- /dev/null +++ b/Books/3-2-事件模块.md @@ -0,0 +1,67 @@ +## 3-2.事件模块 - GameEvent +高效的事件系统GameEventMgr,可以指定事件ID/事件String监听和分发事件。通过事件来驱动模块,如战斗的角色身上的事件流、UI和网络以及Model的数据流、开发中的绝大部分情况都可以通过事件来进行驱动。(配合UI模块或者拓展的战斗模块实现MVE[Model - View - Event]事件驱动架构) + +注:UI模块的事件和UI生命周期存在绑定,销毁UI时可以自动移除UI所监听的事件。(AddUIEvent) +``` csharp +public static int Hellp = StringId.StringToHash("Hellp.Hellp"); + +class A +{ + public A() + { + //添加事件监听string + GameEvent.AddEventListener("TEngine很好用",TodoSomeThings); + //添加事件监听int 事件ID + GameEvent.AddEventListener(Hellp,TodoSomeThings2); + } +} + +class B +{ + private void SaySomeThings() + { + //发送事件流 + GameEvent.Send("TEngine很好用"); + GameEvent.Send(Hellp); + } +} + +【举个例子:游戏中血量扣除的时候,服务器发来了一个减少Hp的消息包, +我们可以在收到这个消息包的时候发送一个事件流,在玩家头顶的HP进度 +条组件/左上角Hp的UI血条组件添加一个监听事件,各个模块负责自己监听后的逻辑】 +Server -> SendMessage(ReduceHP) + +class ClientHandle +{ + private void HandleMessage(MainPack mainpack) + { + ... + HpPack hpPack = mainpack.hpPack; + int playerId = mainpack.playerId; + var player = PlayerMgr.Instance.GetPlayer(playerId); + if(player != null){ + player.Event.Send("Hpchange",hpPack); //局部的事件管理器 + GameEvent.Send("Hpchange",hpPack); //全局事件中心 + } + } +} + +class PlayerHp +{ + public ECSEventCmpt Event { get; set; } + PlayerHp(){ + Event.AddEventListener(Hellp,HandleUpChange); + } +} + +[Window(UILayer.UI)] +class BattleMainUI: UIWindow +{ + public override void RegisterEvent() + { + AddUIEvent(Hellp,HandleUpChange); + } + + public void HandleUpChange(HpPack pack){} +} +``` \ No newline at end of file diff --git a/Books/3-3-内存池模块.md b/Books/3-3-内存池模块.md new file mode 100644 index 00000000..be428926 --- /dev/null +++ b/Books/3-3-内存池模块.md @@ -0,0 +1,18 @@ +## 3-3.内存池模块 - MemoryPool +使用案例 +``` csharp +/// +/// 资源组数据。 +/// DisposeGroup。 +/// +public class AssetGroup : IMemory +{ + public void Clear(){} +} + +//内存池中获取/生成内存对象。 +AssetGroup assetGroup = MemoryPool.Acquire(); + +//释放内存对象还给内存池。 +MemoryPool.Release(assetGroup); +``` \ No newline at end of file diff --git a/Books/3-4-对象池模块.md b/Books/3-4-对象池模块.md new file mode 100644 index 00000000..b7b46aee --- /dev/null +++ b/Books/3-4-对象池模块.md @@ -0,0 +1,47 @@ +## 3-4.对象池模块 - ObjectModule +使用案例 +``` csharp +/// +/// Actor对象。 +/// +public class Actor : ObjectBase +{ + /// + /// 释放对象。 + /// + /// 是否是关闭对象池时触发。 + protected override void Release(bool isShutdown){} +} + +/// +/// Actor对象池。 +/// +private IObjectPool _actorPool; + +void Start() +{ + //创建允许单次获取的对象池。 + _actorPool = GameModule.ObjectPool.CreateSingleSpawnObjectPool(Utility.Text.Format("Actor Instance Pool ({0})", name)); +} + +/// +/// 创建Actor对象。 +/// +/// Actor对象实例。 +public Actor CreateActor() +{ + Actor ret = null; + if (_actorPool.CanSpawn()) + { + ret = _actorPool.Spawn(); + } + else + { + ret = MemoryPool.Acquire(); + _actorPool.Register(ret,true); + } + + return ret; +} + +``` \ No newline at end of file diff --git a/Books/3-5-UI模块.md b/Books/3-5-UI模块.md new file mode 100644 index 00000000..64dc083d --- /dev/null +++ b/Books/3-5-UI模块.md @@ -0,0 +1,5 @@ +## 3-5.UI模块 - UIModule +使用案例 +``` csharp + +``` \ No newline at end of file diff --git a/Books/3-6-配置表模块.md b/Books/3-6-配置表模块.md new file mode 100644 index 00000000..3c2838c0 --- /dev/null +++ b/Books/3-6-配置表模块.md @@ -0,0 +1,4 @@ +## 3-6.配置表模块 - ConfigLoader +``` csharp + +``` \ No newline at end of file diff --git a/Books/0-RunAble.md b/Books/3-7-流程模块.md similarity index 100% rename from Books/0-RunAble.md rename to Books/3-7-流程模块.md diff --git a/Books/3-8-网络模块.md b/Books/3-8-网络模块.md new file mode 100644 index 00000000..0ea28ca8 --- /dev/null +++ b/Books/3-8-网络模块.md @@ -0,0 +1,2 @@ +## 8.网络模块 - Network +待补充 \ No newline at end of file diff --git a/Books/99-各平台运行RunAble.md b/Books/99-各平台运行RunAble.md new file mode 100644 index 00000000..4a7d06c3 --- /dev/null +++ b/Books/99-各平台运行RunAble.md @@ -0,0 +1,15 @@ +# TEngine + +### 日志记录编辑器下运行 +![image](src/Editor-RunSuccessed.png) + +--- +### Win64位包运行 + +![image](src/Win64-RunSuccessed.png) + +--- +### 安卓真机运行 +![image](src/Android-RunSuccessed.png) + +### TODO - IOS环境运行 \ No newline at end of file diff --git a/Books/src/1-1.png b/Books/src/1-1.png new file mode 100644 index 00000000..46834a7e Binary files /dev/null and b/Books/src/1-1.png differ diff --git a/Books/src/1-2.png b/Books/src/1-2.png new file mode 100644 index 00000000..313e4782 Binary files /dev/null and b/Books/src/1-2.png differ diff --git a/Books/src/2-1.png b/Books/src/2-1.png new file mode 100644 index 00000000..1ab634f6 Binary files /dev/null and b/Books/src/2-1.png differ