Compare commits
227 Commits
TEngine4.0
...
yoo2.2.9
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5887133894 | ||
![]() |
6166fd24c6 | ||
![]() |
634a392a1f | ||
![]() |
b869a05220 | ||
![]() |
37d88c2d94 | ||
![]() |
f3aa8824d8 | ||
![]() |
99c5afcbc5 | ||
![]() |
4075588c34 | ||
![]() |
fdd9f34132 | ||
![]() |
a2ab6efc71 | ||
![]() |
67025c806e | ||
![]() |
38afa45f9c | ||
![]() |
0dc572f43e | ||
![]() |
0679d924c1 | ||
![]() |
3de8cad99a | ||
![]() |
065d5a7303 | ||
![]() |
c089eb32ba | ||
![]() |
d571a937f8 | ||
![]() |
89210483a9 | ||
![]() |
058ac2c9a5 | ||
![]() |
990222c7c6 | ||
![]() |
d3914a96bb | ||
![]() |
4b178a9fa9 | ||
![]() |
79929c4ac3 | ||
![]() |
38fa4d5cbc | ||
![]() |
3ac6977f93 | ||
![]() |
3facec8f93 | ||
![]() |
0570982b97 | ||
![]() |
f785264873 | ||
![]() |
4911ec074c | ||
![]() |
6ff9546152 | ||
![]() |
5a8dc04b9c | ||
![]() |
d4482cf1c4 | ||
![]() |
c7fad139ba | ||
![]() |
650469a7db | ||
![]() |
c7c00eac9f | ||
![]() |
5a883bc8ec | ||
![]() |
79c1026c7c | ||
![]() |
f2c69d58b2 | ||
![]() |
c38d3b7cfa | ||
![]() |
98cb74537a | ||
![]() |
ed19a75be9 | ||
![]() |
fd82ddf427 | ||
![]() |
e53ceb0095 | ||
![]() |
9afda78735 | ||
![]() |
5734d4f995 | ||
![]() |
dc7ab7fd64 | ||
![]() |
fcb3416acd | ||
![]() |
3df18c006d | ||
![]() |
6cfae215dc | ||
![]() |
1aaa46c82c | ||
![]() |
ca79adce7c | ||
![]() |
b520eba187 | ||
![]() |
b5afaca217 | ||
![]() |
ea2efbf588 | ||
![]() |
a4b1befc5a | ||
![]() |
8dcddfa328 | ||
![]() |
dd37d130da | ||
![]() |
24d7dbc677 | ||
![]() |
491100b932 | ||
![]() |
c84c21574d | ||
![]() |
7914660f8c | ||
![]() |
b00679a276 | ||
![]() |
cd9a10ccac | ||
![]() |
f11098d32e | ||
![]() |
db6e715fa6 | ||
![]() |
c2edf71ee4 | ||
![]() |
75af7c22c7 | ||
![]() |
2f9edf83bf | ||
![]() |
815095efaf | ||
![]() |
3101a64a48 | ||
![]() |
457e0f36a4 | ||
![]() |
0bd30def23 | ||
![]() |
d24db83c8b | ||
![]() |
18a2840777 | ||
![]() |
1d901514e1 | ||
![]() |
983279c56d | ||
![]() |
e9540c620a | ||
![]() |
39be280d88 | ||
![]() |
f9f9122027 | ||
![]() |
682a0bd786 | ||
![]() |
34c514cae8 | ||
![]() |
c707cc1a38 | ||
![]() |
f016fdd0a6 | ||
![]() |
4c0f5a77f9 | ||
![]() |
ae0d00424f | ||
![]() |
c8ecac5815 | ||
![]() |
4f8c1cdfdd | ||
![]() |
dff043e075 | ||
![]() |
e69dc47b8f | ||
![]() |
fc2ef0714c | ||
![]() |
d75c1c8c93 | ||
![]() |
83bea559e4 | ||
![]() |
26689639ed | ||
![]() |
bd6ac5f4da | ||
![]() |
70dcb03a3f | ||
![]() |
59b3649155 | ||
![]() |
2c025efe3b | ||
![]() |
7ae6ef94ba | ||
![]() |
d5bb64b314 | ||
![]() |
4c34858ce0 | ||
![]() |
5adb2f83e5 | ||
![]() |
f10a89180e | ||
![]() |
3e3314858e | ||
![]() |
da57ed845f | ||
![]() |
df570f453a | ||
![]() |
a500a08a30 | ||
![]() |
2daac0e065 | ||
![]() |
514da6e99e | ||
![]() |
7f91241df7 | ||
![]() |
071974ab4f | ||
![]() |
c01e03ff70 | ||
![]() |
6fec792e05 | ||
![]() |
04ecf71eab | ||
![]() |
693ca5bb3d | ||
![]() |
90f84a2764 | ||
![]() |
6107b41770 | ||
![]() |
1423a3716a | ||
![]() |
6a87db76ee | ||
![]() |
3a6170dca6 | ||
![]() |
9d137d613a | ||
![]() |
ba77ec6b45 | ||
![]() |
b661da68f2 | ||
![]() |
e1040110bb | ||
![]() |
2d53fa1687 | ||
![]() |
c4ef07f13e | ||
![]() |
1f2d99ddc9 | ||
![]() |
edf4925a7a | ||
![]() |
5d67238c8f | ||
![]() |
6cfd352482 | ||
![]() |
40373c473d | ||
![]() |
d799f9fdf0 | ||
![]() |
15735c3d2d | ||
![]() |
818a74f437 | ||
![]() |
f248757401 | ||
![]() |
6ada0e7de7 | ||
![]() |
7ea472f97e | ||
![]() |
fb8528ff52 | ||
![]() |
e3ac92ef46 | ||
![]() |
be6a19c26a | ||
![]() |
e7f0636f30 | ||
![]() |
fb38e96e9e | ||
![]() |
dd658c7e1d | ||
![]() |
4d7cb7641d | ||
![]() |
ae075b1fad | ||
![]() |
02827ce3b8 | ||
![]() |
1a0e3f91e0 | ||
![]() |
6d376b0e07 | ||
![]() |
cb73c9a9eb | ||
![]() |
7dda73a7ac | ||
![]() |
9bcb636ed7 | ||
![]() |
bd0cfc5577 | ||
![]() |
ff613e4130 | ||
![]() |
fea1ae2278 | ||
![]() |
866c440479 | ||
![]() |
48ff839d64 | ||
![]() |
69be3cfa23 | ||
![]() |
5f2c27ecf0 | ||
![]() |
ef17cd851b | ||
![]() |
f186d6b058 | ||
![]() |
4385123976 | ||
![]() |
1334dc30f9 | ||
![]() |
af822add2c | ||
![]() |
ffb1f214ad | ||
![]() |
213aaed426 | ||
![]() |
623d301e41 | ||
![]() |
2870383afe | ||
![]() |
1ad435958a | ||
![]() |
386787c6ec | ||
![]() |
cd65dde4c3 | ||
![]() |
8321e77421 | ||
![]() |
1b6f80952e | ||
![]() |
b52e655c30 | ||
![]() |
8c0df95626 | ||
![]() |
0d1e308f1c | ||
![]() |
f8797538fd | ||
![]() |
fe4e168041 | ||
![]() |
8e9047d3a3 | ||
![]() |
04bfaeccc8 | ||
![]() |
d66c823c15 | ||
![]() |
0ec1424f0a | ||
![]() |
01f8eb9d57 | ||
![]() |
f5021a9688 | ||
![]() |
a632f7a5ad | ||
![]() |
5f968f4154 | ||
![]() |
c9fe83c2bd | ||
![]() |
2c00d103cb | ||
![]() |
1d56437d9f | ||
![]() |
69db1ff977 | ||
![]() |
48887b1aee | ||
![]() |
381ea8bb8d | ||
![]() |
7401edac15 | ||
![]() |
b1c7f30be9 | ||
![]() |
cfaf82a623 | ||
![]() |
6992d12c6c | ||
![]() |
119d9683ad | ||
![]() |
9478868513 | ||
![]() |
6ed32082e1 | ||
![]() |
6ee515e8c5 | ||
![]() |
b839afa76a | ||
![]() |
d9605b348a | ||
![]() |
dfef83919c | ||
![]() |
f5f983f220 | ||
![]() |
d61b1206ee | ||
![]() |
3650ba1a8b | ||
![]() |
8f14a4d2cb | ||
![]() |
dc22e595c9 | ||
![]() |
0e70f7d446 | ||
![]() |
039569b2d4 | ||
![]() |
ea38004ba2 | ||
![]() |
cc97c0583a | ||
![]() |
887094a4b1 | ||
![]() |
0d09a7e73b | ||
![]() |
d8f8514f9d | ||
![]() |
f2f6b2422f | ||
![]() |
3a9cad9397 | ||
![]() |
5e70e7972e | ||
![]() |
8d2b4200d6 | ||
![]() |
b983e85416 | ||
![]() |
99d2afdbd7 | ||
![]() |
57ce836b3c | ||
![]() |
8dce78d6fb | ||
![]() |
6d41adffd9 | ||
![]() |
cb9129261b | ||
![]() |
89dd6214d4 | ||
![]() |
1aec76d64c | ||
![]() |
859f654f6d |
@@ -13,11 +13,12 @@
|
||||

|
||||
|
||||
### 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,打包并且运行热更新示例工程。
|
||||
* 1.运行菜单 HybridCLR/Install... 安装HybridCLR,每次更新HybridCLR版本需要重新执行一次安装。
|
||||
* 2.运行菜单 HybridCLR/Define Symbols/Enable HybridCLR 运行开启HybridCLR热更新。
|
||||
* 3.运行菜单 HybridCLR/Generate/All 进行必要的生成操作。这一步不可遗漏!!!
|
||||
* 4.运行菜单 HybridCLR/Build/BuildAssets And CopyTo AssemblyPath,生成热更新dll并copy到热更程序集中。
|
||||
* 5.运行菜单 YooAsset/AssetBundle Builder 构建AB。
|
||||
* 6.打开Build Settings对话框,点击Build And Run,打包并且运行热更新示例工程。
|
||||
|
||||
### 遇到问题请查看HybridlCLR的<a href="https://hybridclr.doc.code-philosophy.com/docs/help/commonerrors"><strong>常见错误(commonerrors)</strong></a>
|
||||
|
||||
@@ -33,26 +34,30 @@
|
||||
### 目录结构
|
||||
```
|
||||
Assets
|
||||
├── AssetRaw 资源目录
|
||||
├── Atlas 图集目录
|
||||
├── GameScripts 热更程序集目录
|
||||
├── Scenes 主场景目录
|
||||
└── TEngine
|
||||
├── AssetSetting YooAsset资源设置
|
||||
├── Editor TEngine-Editor程序集
|
||||
└── Runtime TEngine-Runtime程序集
|
||||
├── AssetArt // 美术资源目录
|
||||
│ └── Atlas // 自动生成图集目录
|
||||
├── AssetRaw // 热更资源目录
|
||||
│ ├── UIRaw // UI图片目录
|
||||
│ │ ├── Atlas // 需要自动生成图集的UI素材目录
|
||||
│ │ └── Raw // 不需要自动生成图集的UI素材目录
|
||||
├── Editor // 编辑器脚本目录
|
||||
├── HybridCLRData // hybridclr相关目录
|
||||
├── Scenes // 主场景目录
|
||||
├── GameScripts // 程序集目录
|
||||
└── 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程序集
|
||||
├── Main // 主程序程序集(启动器与流程)
|
||||
└── HotFix // 游戏热更程序集目录 [Folder]
|
||||
├── GameBase // 游戏基础框架程序集 [Dll]
|
||||
├── GameProto // 游戏配置协议程序集 [Dll]
|
||||
└── GameLogic // 游戏业务逻辑程序集 [Dll]
|
||||
├── GameApp.cs // 热更主入口
|
||||
└── GameApp_RegisterSystem.cs // 热更主入口注册系统
|
||||
```
|
@@ -1,16 +1,16 @@
|
||||
# TEngine
|
||||
|
||||
## TEngine-Runtime
|
||||
### AOT内核基于Gameframework,最简化以及商业化适配。
|
||||
### AOT内核基于Gameframework,优化、最简化以及商业化适配。
|
||||

|
||||
|
||||
## AOT游戏框架模块基类。
|
||||
#### 框架思路为面向接口编程,如Resource资源模块,开发白皮书为先定义IResourceManager的接口规范,然后编写ResourceManager继承框架具体实现(GameFrameworkModule)以及实现接口。最后实现调用层GameFrameworkModuleBase,调用层可以拓展编辑器供开发者自定义模块参数。
|
||||
#### 框架思路为面向接口编程,如Resource资源模块,开发白皮书为先定义IResourceManager的接口规范,然后编写ResourceManager继承框架具体实现(ModuleImp)以及实现接口。最后实现调用层Module,调用层可以拓展编辑器供开发者自定义模块参数。
|
||||
``` csharp
|
||||
/// <summary>
|
||||
/// 游戏框架模块抽象类。GameFrameworkModule为具体框架模块实现。
|
||||
/// 游戏框架模块抽象类。ModuleImp为具体框架模块实现。
|
||||
/// </summary>
|
||||
internal abstract class GameFrameworkModule
|
||||
internal abstract class ModuleImp
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取游戏框架模块优先级。
|
||||
@@ -34,16 +34,16 @@ internal abstract class GameFrameworkModule
|
||||
//=====================================================================//
|
||||
|
||||
/// <summary>
|
||||
/// 游戏框架模块抽象类。GameFrameworkModuleBase 为Mono调用层。
|
||||
/// 游戏框架模块抽象类。Module 为Mono调用层。
|
||||
/// </summary>
|
||||
public abstract class GameFrameworkModuleBase : MonoBehaviour
|
||||
public abstract class Module : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架模块初始化。
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
GameEntry.RegisterModule(this);
|
||||
ModuleSystem.RegisterModule(this);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -51,17 +51,15 @@ public abstract class GameFrameworkModuleBase : MonoBehaviour
|
||||
## 热更域程序集设计与说明
|
||||
```
|
||||
Assets/GameScripts
|
||||
├── Editor 编辑器程序集
|
||||
├── HotFix 游戏热更程序集目录 [Folder]
|
||||
| ├── GameBase 游戏基础框架程序集 [Dll]
|
||||
| ├── GameProto 游戏配置协议程序集 [Dll]
|
||||
| ├── BattleCore 游戏核心战斗程序集 [Dll]
|
||||
| └── GameLogic 游戏业务逻辑程序集 [Dll]
|
||||
| ├── GameApp.cs 热更主入口
|
||||
| └── GameApp_RegisterSystem.cs 热更主入口注册系统
|
||||
└── Runtime Runtime程序集
|
||||
├── Main // 主程序程序集(启动器与流程)
|
||||
└── HotFix // 游戏热更程序集目录 [Folder]
|
||||
├── GameBase // 游戏基础框架程序集 [Dll]
|
||||
├── GameProto // 游戏配置协议程序集 [Dll]
|
||||
└── GameLogic // 游戏业务逻辑程序集 [Dll]
|
||||
├── GameApp.cs 热更主入口
|
||||
└── GameApp_RegisterSystem.cs 热更主入口注册系统
|
||||
```
|
||||
游戏内主要玩法逻辑包括UI会在GameLogic中编写,GameBase则存放一些通用性的逻辑,GameProto存放与服务区交互的协议以及配置表逻辑,BattleCore为帧同步分离的逻辑层做预留。若有项目需求完全可以进行自定义增删HotFix程序集。
|
||||
游戏内主要玩法逻辑包括UI会在GameLogic中编写,GameBase则存放一些通用性的逻辑,GameProto存放与服务区交互的协议以及配置表逻辑。若有项目需求完全可以进行自定义增删HotFix程序集。
|
||||
|
||||
PS:注意增删程序集后需要同步到HybridClr的Setting面板以及TEngineSetting的面板。TEngineSettings面板有按钮可以从HybridClr中同步AOT与热更程序集。
|
||||
|
||||
|
@@ -1,11 +1,19 @@
|
||||
# 3-6.配置表模块 - ConfigLoader
|
||||
# 3-6.配置表模块 - ConfigSystem
|
||||
接入最佳游戏配置解决方案 - <a href="https://github.com/focus-creative-games/luban"><strong>Luban</strong></a>
|
||||
|
||||
<a href="https://luban.doc.code-philosophy.com/#/manual/traits"><strong>Luban文档 </strong></a>
|
||||
|
||||
### 在TEngine中Luban工具集位于以下目录
|
||||
### 在TEngine中Luban配置表目录位于以下目录
|
||||

|
||||
|
||||
### 安装luban配置表
|
||||
1.在TEngine根目录同级克隆下最新的luban-next仓库。
|
||||

|
||||
2.Tools目录执行build-luban完成
|
||||

|
||||
|
||||
3.转表则去luban配置目录执行对应bat
|
||||
|
||||
TEngine内置默认使用懒加载配置,也支持基于UniTask的异步加载,同步加载,包括服务器的Task异步加载,使用对应转表的bat即可。
|
||||
|
||||
### 介绍
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
### ProcedureInitPackage - 流程初始化Package
|
||||
|
||||
### ProcedurePreload - 流程预加载
|
||||
|
||||
### ProcedureInitResources - 流程初始化Resources
|
||||
|
||||
### ProcedureUpdateVersion - 流程更新版本Version
|
||||
@@ -20,5 +22,6 @@
|
||||
|
||||
### ProcedureClearCache - 流程清理缓存
|
||||
|
||||
### ProcedureLoadAssembly - 流程加载进入热更新程序集
|
||||
|
||||
### ProcedureLoadAssembly - 流程加载进入热更新程序集
|
||||
### ProcedureStartGame - 流程开始游戏
|
@@ -13,4 +13,14 @@
|
||||

|
||||
|
||||
### IOS真机运行
|
||||

|
||||

|
||||
|
||||
### WebGL真机运行
|
||||

|
||||
|
||||
### 索尼 PS5 真机运行
|
||||
|
||||

|
||||
|
||||
|
||||

|
16
Books/Donate.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## <strong>Buy me a coffee.
|
||||
|
||||
您的赞助会让我们做得更快更好,如果觉得TEngine对您有帮助,不妨赞助我买杯咖啡吧~
|
||||
|
||||
|
||||
<p align="center">
|
||||
|
||||
<img src="src/Donate-微信.jpg" alt="logo" width="384" height="562">
|
||||
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
||||
<img src="src/Donate-支付宝.jpg" alt="logo" width="384" height="562">
|
||||
|
||||
</p>
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 74 KiB |
BIN
Books/src/3-6-2.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
Books/src/3-6-3.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
Books/src/Console Output.png
Normal file
After Width: | Height: | Size: 124 KiB |
BIN
Books/src/Console Viewer.png
Normal file
After Width: | Height: | Size: 477 KiB |
BIN
Books/src/Donate-微信.jpg
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
Books/src/Donate-支付宝.jpg
Normal file
After Width: | Height: | Size: 214 KiB |
BIN
Books/src/WebGL-RunSuccessed.png
Normal file
After Width: | Height: | Size: 101 KiB |
9
BuildCLI/build_android.bat
Normal file
@@ -0,0 +1,9 @@
|
||||
cd /d %~dp0
|
||||
|
||||
call path_define.bat
|
||||
|
||||
%UNITYEDITOR_PATH%/Unity.exe %WORKSPACE% -logFile %BUILD_LOGFILE% -executeMethod TEngine.ReleaseTools.AutomationBuildAndroid -quit -batchmode -CustomArgs:Language=en_US; %WORKSPACE%
|
||||
|
||||
@REM for /f "delims=[" %%i in (%BUILD_LOGFILE%) do echo %%i
|
||||
|
||||
pause
|
18
BuildCLI/build_android.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
source ./path_define.sh
|
||||
|
||||
"${UNITYEDITOR_PATH}/Unity" "${WORKSPACE}" \
|
||||
-logFile "${BUILD_LOGFILE}" \
|
||||
-executeMethod TEngine.ReleaseTools.AutomationBuildAndroid \
|
||||
-quit -batchmode \
|
||||
-CustomArgs:Language=en_US "${WORKSPACE}"
|
||||
|
||||
while IFS= read -r line; do
|
||||
echo "$line"
|
||||
done < "${BUILD_LOGFILE}"
|
||||
|
||||
echo "按任意键继续..."
|
||||
read -k1
|
6
BuildCLI/path_define.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
cd /d %~dp0
|
||||
|
||||
set WORKSPACE=G:/github/TEngine/UnityProject
|
||||
set UNITYEDITOR_PATH=G:/UnityEditor/2021.3.20f1c1/Editor
|
||||
set BUILD_DLL_LOGFILE=./build_dll.log
|
||||
set BUILD_LOGFILE=./build.log
|
14
BuildCLI/path_define.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
export WORKSPACE="/Users/your_user/github/TEngine/UnityProject" # 请替换为 macOS 上的实际路径
|
||||
export UNITYEDITOR_PATH="/Applications/Unity/Hub/Editor/2021.3.20f1c1/Unity.app/Contents/MacOS" # 请替换为 macOS 上的 Unity 路径
|
||||
export BUILD_DLL_LOGFILE="./build_dll.log"
|
||||
export BUILD_LOGFILE="./build.log"
|
||||
|
||||
echo "环境变量已设置:"
|
||||
echo "WORKSPACE=${WORKSPACE}"
|
||||
echo "UNITYEDITOR_PATH=${UNITYEDITOR_PATH}"
|
||||
echo "BUILD_DLL_LOGFILE=${BUILD_DLL_LOGFILE}"
|
||||
echo "BUILD_LOGFILE=${BUILD_LOGFILE}"
|
@@ -1,61 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using GameBase;
|
||||
using GameConfig;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 配置加载器。
|
||||
/// </summary>
|
||||
public class ConfigSystem : Singleton<ConfigSystem>
|
||||
{
|
||||
private bool _init = false;
|
||||
|
||||
private Tables _tables;
|
||||
|
||||
public Tables Tables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
return _tables;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载配置。
|
||||
/// </summary>
|
||||
public void Load()
|
||||
{
|
||||
_tables = new Tables(LoadIdxByteBuf, LoadByteBuf);
|
||||
_init = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载二进制配置。
|
||||
/// </summary>
|
||||
/// <param name="file">FileName</param>
|
||||
/// <returns>ByteBuf</returns>
|
||||
private ByteBuf LoadByteBuf(string file)
|
||||
{
|
||||
var textAssets = GameModule.Resource.LoadAsset<TextAsset>(file);
|
||||
byte[] ret = textAssets.bytes;
|
||||
return new ByteBuf(ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载懒加载Index。
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private ByteBuf LoadIdxByteBuf(string file)
|
||||
{
|
||||
var textAssets = GameModule.Resource.LoadAsset<TextAsset>($"Idx_{file}");
|
||||
byte[] ret = textAssets.bytes;
|
||||
return new ByteBuf(ret);
|
||||
}
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
{{
|
||||
name = x.name
|
||||
parent_def_type = x.parent_def_type
|
||||
export_fields = x.export_fields
|
||||
hierarchy_export_fields = x.hierarchy_export_fields
|
||||
}}
|
||||
|
||||
|
||||
namespace {{x.namespace_with_top_module}}
|
||||
{
|
||||
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Config.BeanBase {{end}}
|
||||
{
|
||||
public {{name}}(ByteBuf _buf) {{if parent_def_type}} : base(_buf) {{end}}
|
||||
{
|
||||
{{~ for field in export_fields ~}}
|
||||
{{cs_deserialize '_buf' field.convention_name field.ctype}}
|
||||
{{~if field.index_field~}}
|
||||
foreach(var _v in {{field.convention_name}})
|
||||
{
|
||||
{{field.convention_name}}_Index.Add(_v.{{field.index_field.convention_name}}, _v);
|
||||
}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public static {{name}} Deserialize{{name}}(ByteBuf _buf)
|
||||
{
|
||||
{{~if x.is_abstract_type~}}
|
||||
switch (_buf.ReadInt())
|
||||
{
|
||||
{{~for child in x.hierarchy_not_abstract_children~}}
|
||||
case {{child.full_name}}.__ID__: return new {{child.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
default: throw new SerializationException();
|
||||
}
|
||||
{{~else~}}
|
||||
return new {{x.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} { get; private set; }
|
||||
{{~if field.index_field~}}
|
||||
public readonly Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}> {{field.convention_name}}_Index = new Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}>();
|
||||
{{~end~}}
|
||||
{{~if field.gen_ref~}}
|
||||
public {{field.cs_ref_validator_define}}
|
||||
{{~end~}}
|
||||
{{~if (gen_datetime_mills field.ctype) ~}}
|
||||
public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L;
|
||||
{{~end~}}
|
||||
{{~if field.gen_text_key~}}
|
||||
public {{cs_define_text_key_field field}} { get; }
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
{{~if !x.is_abstract_type~}}
|
||||
public const int __ID__ = {{x.id}};
|
||||
public override int GetTypeId() => __ID__;
|
||||
{{~end~}}
|
||||
public override string ToString()
|
||||
{
|
||||
return "{{full_name}}{ "
|
||||
{{~for field in hierarchy_export_fields ~}}
|
||||
+ "{{field.convention_name}}:" + {{cs_to_string field.convention_name field.ctype}} + ","
|
||||
{{~end~}}
|
||||
+ "}";
|
||||
}
|
||||
|
||||
partial void PostInit();
|
||||
}
|
||||
|
||||
}
|
@@ -1,413 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace {{x.namespace_with_top_module}}
|
||||
{
|
||||
{{
|
||||
name = x.name
|
||||
key_type = x.key_ttype
|
||||
key_type1 = x.key_ttype1
|
||||
key_type2 = x.key_ttype2
|
||||
value_type = x.value_ttype
|
||||
}}
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public partial class {{name}}
|
||||
{
|
||||
public static {{name}} Instance { get; private set; }
|
||||
{{~if x.is_map_table ~}}
|
||||
private bool _readAll = false;
|
||||
private Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> _dataMap;
|
||||
private List<{{cs_define_type value_type}}> _dataList;
|
||||
public Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> DataMap
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAll)
|
||||
{
|
||||
ReadAll();
|
||||
_readAll = true;
|
||||
}
|
||||
return _dataMap;
|
||||
}
|
||||
}
|
||||
public List<{{cs_define_type value_type}}> DataList
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAll)
|
||||
{
|
||||
ReadAll();
|
||||
_readAll = true;
|
||||
}
|
||||
return _dataList;
|
||||
}
|
||||
}
|
||||
private Dictionary<{{cs_define_type key_type}},int> _indexMap;
|
||||
public List<{{cs_define_type key_type}}> Indexes;
|
||||
private System.Func<ByteBuf> _dataLoader;
|
||||
|
||||
private void ReadAll()
|
||||
{
|
||||
_dataList.Clear();
|
||||
foreach(var index in Indexes)
|
||||
{
|
||||
var v = Get(index);
|
||||
_dataMap[index] = v;
|
||||
_dataList.Add(v);
|
||||
}
|
||||
}
|
||||
|
||||
public {{name}}(ByteBuf _buf, string _tbName, System.Func<string, ByteBuf> _loader)
|
||||
{
|
||||
Instance = this;
|
||||
_dataMap = new Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}>();
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
_indexMap = new Dictionary<{{cs_define_type key_type}}, int>();
|
||||
_dataLoader = new System.Func<ByteBuf>(() => _loader(_tbName));
|
||||
|
||||
for (int n = _buf.ReadSize(); n > 0; --n)
|
||||
{
|
||||
{{cs_define_type key_type}} key;
|
||||
{{cs_deserialize '_buf' 'key' key_type}}
|
||||
int index = _buf.ReadInt();
|
||||
_indexMap[key] = index;
|
||||
}
|
||||
Indexes = _indexMap.Keys.ToList();
|
||||
PostInit();
|
||||
}
|
||||
|
||||
{{~if value_type.is_dynamic~}}
|
||||
public T GetOrDefaultAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}}
|
||||
{
|
||||
if(_indexMap.TryGetValue(key,out var _))
|
||||
{
|
||||
return (T)Get(key);
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
public T GetAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}} => (T)Get(key);
|
||||
{{~end~}}
|
||||
public {{cs_define_type value_type}} this[{{cs_define_type key_type}} key] => Get(key);
|
||||
public {{cs_define_type value_type}} Get({{cs_define_type key_type}} key)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
if(_dataMap.TryGetValue(key, out _v))
|
||||
{
|
||||
return _v;
|
||||
}
|
||||
ResetByteBuf(_indexMap[key]);
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataMap[_v.{{x.index_field.convention_name}}] = _v;
|
||||
_v.Resolve(tables);
|
||||
if(_indexMap.Count == _dataMap.Count)
|
||||
{
|
||||
_buf = null;
|
||||
}
|
||||
return _v;
|
||||
}
|
||||
public {{cs_define_type value_type}} GetOrDefault({{cs_define_type key_type}} key)
|
||||
{
|
||||
if(_indexMap.TryGetValue(key,out var _))
|
||||
{
|
||||
return Get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
{{~else if x.is_list_table ~}}
|
||||
private bool _readAllList = false;
|
||||
private List<{{cs_define_type value_type}}> _dataList;
|
||||
public List<{{cs_define_type value_type}}> DataList
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAllList)
|
||||
{
|
||||
ReadAllList();
|
||||
_readAllList = true;
|
||||
}
|
||||
return _dataList;
|
||||
}
|
||||
}
|
||||
private System.Func<ByteBuf> _dataLoader;
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
private bool _readAll;
|
||||
private {{cs_table_union_map_type_name x}} _dataMapUnion;
|
||||
public {{cs_table_union_map_type_name x}} DataMapUnion
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAll)
|
||||
{
|
||||
ReadAll();
|
||||
_readAll = true;
|
||||
}
|
||||
return _dataMapUnion;
|
||||
}
|
||||
}
|
||||
private void ReadAll()
|
||||
{
|
||||
foreach(var index in Indexes)
|
||||
{
|
||||
var ({{cs_table_get_param_name_list x}}) = index;
|
||||
var v = Get({{cs_table_get_param_name_list x}});
|
||||
_dataMapUnion[({{cs_table_get_param_name_list x}})] = v;
|
||||
}
|
||||
}
|
||||
private void ReadAllList()
|
||||
{
|
||||
_dataList.Clear();
|
||||
foreach(var index in Indexes)
|
||||
{
|
||||
var ({{cs_table_get_param_name_list x}}) = index;
|
||||
var v = Get({{cs_table_get_param_name_list x}});
|
||||
_dataList.Add(v);
|
||||
}
|
||||
}
|
||||
private Dictionary<({{cs_table_get_param_def_list x}}),int> _indexMap;
|
||||
public List<({{cs_table_get_param_def_list x}})> Indexes;
|
||||
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
private bool _readAll{{idx.index_field.convention_name}} = false;
|
||||
private Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}> _dataMap_{{idx.index_field.name}};
|
||||
public Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}> DataMap_{{idx.index_field.name}}
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAll{{idx.index_field.convention_name}})
|
||||
{
|
||||
ReadAll{{idx.index_field.convention_name}}();
|
||||
_readAll{{idx.index_field.convention_name}} = true;
|
||||
}
|
||||
return _dataMap_{{idx.index_field.name}};
|
||||
}
|
||||
}
|
||||
{{~if for.first ~}}
|
||||
private void ReadAllList()
|
||||
{
|
||||
_dataList.Clear();
|
||||
foreach(var index in Indexes_{{idx.index_field.name}})
|
||||
{
|
||||
var v = GetBy{{idx.index_field.convention_name}}(index);
|
||||
_dataList.Add(v);
|
||||
}
|
||||
}
|
||||
{{~end~}}
|
||||
private void ReadAll{{idx.index_field.convention_name}}()
|
||||
{
|
||||
foreach(var index in Indexes_{{idx.index_field.name}})
|
||||
{
|
||||
var v = GetBy{{idx.index_field.convention_name}}(index);
|
||||
_dataMap_{{idx.index_field.name}}[index] = v;
|
||||
}
|
||||
}
|
||||
private Dictionary<{{cs_define_type idx.type}},int> _indexMap_{{idx.index_field.name}};
|
||||
public List<{{cs_define_type idx.type}}> Indexes_{{idx.index_field.name}};
|
||||
{{~end~}}
|
||||
{{~else~}}
|
||||
private bool _readAll = false;
|
||||
private Dictionary<int,int> _indexMap;
|
||||
public List<int> Indexes;
|
||||
private Dictionary<int, {{cs_define_type value_type}}> _dataMap;
|
||||
private Dictionary<int, {{cs_define_type value_type}}> DataMap
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!_readAll)
|
||||
{
|
||||
ReadAllList();
|
||||
}
|
||||
return _dataMap;
|
||||
}
|
||||
}
|
||||
private void ReadAllList()
|
||||
{
|
||||
_dataList.Clear();
|
||||
foreach(var index in Indexes)
|
||||
{
|
||||
var v = Get(index);
|
||||
_dataList.Add(v);
|
||||
}
|
||||
}
|
||||
{{~end~}}
|
||||
public {{name}}(ByteBuf _buf, string _tbName, System.Func<string, ByteBuf> _loader)
|
||||
{
|
||||
Instance = this;
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
_dataLoader = new System.Func<ByteBuf>(()=> _loader(_tbName));
|
||||
{{~if x.is_union_index~}}
|
||||
_dataMapUnion = new {{cs_table_union_map_type_name x}}();
|
||||
_indexMap = new Dictionary<({{cs_table_get_param_def_list x}}),int>();
|
||||
{{key_value ='('}}
|
||||
for (int i = _buf.ReadSize(); i > 0; i--)
|
||||
{
|
||||
{{~for idx in x.index_list~}}
|
||||
{{field_name = 'key'+for.index}}
|
||||
{{cs_define_type idx.type}} {{field_name}};
|
||||
{{cs_deserialize '_buf' field_name idx.type}}
|
||||
{{~if for.last~}}
|
||||
{{key_value=key_value+field_name+')'}}
|
||||
{{~else~}}
|
||||
{{key_value=key_value+field_name+', '}}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
_indexMap.Add({{key_value}}, _buf.ReadInt());
|
||||
}
|
||||
Indexes = _indexMap.Keys.ToList();
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
_dataMap_{{idx.index_field.name}} = new Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}>();
|
||||
_indexMap_{{idx.index_field.name}} = new Dictionary<{{cs_define_type idx.type}},int>();
|
||||
{{~end~}}
|
||||
|
||||
|
||||
int size = _buf.ReadSize();
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
{{~for idx in x.index_list~}}
|
||||
{{cs_define_type idx.type}} key_{{idx.index_field.name}};
|
||||
{{cs_deserialize '_buf' 'key_'+idx.index_field.name idx.type}}
|
||||
{{~end~}}
|
||||
int index = _buf.ReadInt();
|
||||
{{~for idx in x.index_list~}}
|
||||
_indexMap_{{idx.index_field.name}}.Add(key_{{idx.index_field.name}},index);
|
||||
{{~end~}}
|
||||
}
|
||||
{{~for idx in x.index_list~}}
|
||||
Indexes_{{idx.index_field.name}} = _indexMap_{{idx.index_field.name}}.Keys.ToList();
|
||||
{{~end~}}
|
||||
{{~else~}}
|
||||
_indexMap = new Dictionary<int,int>();
|
||||
_dataMap = new Dictionary<int, {{cs_define_type value_type}}>();
|
||||
int size = _buf.ReadSize();
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
_indexMap.Add(i,_buf.ReadInt());
|
||||
}
|
||||
Indexes = _indexMap.Keys.ToList();
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
public {{cs_define_type value_type}} Get({{cs_table_get_param_def_list x}})
|
||||
{
|
||||
{{cs_define_type value_type}} __v;
|
||||
if(_dataMapUnion.TryGetValue(({{cs_table_get_param_name_list x}}), out __v))
|
||||
{
|
||||
return __v;
|
||||
}
|
||||
ResetByteBuf(_indexMap[({{cs_table_get_param_name_list x}})]);
|
||||
|
||||
{{cs_deserialize '_buf' '__v' value_type}}
|
||||
_dataList.Add(__v);
|
||||
_dataMapUnion.Add(({{cs_table_get_param_name_list x}}), __v);
|
||||
__v.Resolve(tables);
|
||||
if(_indexMap.Count == _dataMapUnion.Count)
|
||||
{
|
||||
_buf = null;
|
||||
}
|
||||
return __v;
|
||||
}
|
||||
{{~else if !x.index_list.empty? ~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
public {{cs_define_type value_type}} GetBy{{idx.index_field.convention_name}}({{cs_define_type idx.type}} key)
|
||||
{
|
||||
if(_dataMap_{{idx.index_field.name}}.TryGetValue(key,out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
int index = _indexMap_{{idx.index_field.name}}[key];
|
||||
ResetByteBuf(index);
|
||||
{{cs_define_type value_type}} _v;
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataMap_{{idx.index_field.name}}[key] = _v;
|
||||
_v.Resolve(tables);
|
||||
return _v;
|
||||
}
|
||||
{{~end~}}
|
||||
{{~else if x.index_list.empty? ~}}
|
||||
public {{cs_define_type value_type}} this[int index] => Get(index);
|
||||
public {{cs_define_type value_type}} Get(int index)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
if(_dataMap.TryGetValue(index, out _v))
|
||||
{
|
||||
return _v;
|
||||
}
|
||||
ResetByteBuf(_indexMap[index]);
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataMap[index] = _v;
|
||||
_v.Resolve(tables);
|
||||
if(_indexMap.Count == _dataMap.Count)
|
||||
{
|
||||
_buf = null;
|
||||
}
|
||||
return _v;
|
||||
}
|
||||
{{~end~}}
|
||||
{{~else~}}
|
||||
|
||||
private {{cs_define_type value_type}} _data;
|
||||
|
||||
public {{name}} (ByteBuf _buf, string _tbName, System.Func<string, ByteBuf> _loader)
|
||||
{
|
||||
Instance = this;
|
||||
ByteBuf _dataBuf = _loader(_tbName);
|
||||
int n = _buf.ReadSize();
|
||||
int m = _dataBuf.ReadSize();
|
||||
if (n != 1 || m != 1) throw new SerializationException("table mode=one, but size != 1");
|
||||
{{cs_deserialize '_dataBuf' '_data' value_type}}
|
||||
}
|
||||
|
||||
|
||||
{{~ for field in value_type.bean.hierarchy_export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} => _data.{{field.convention_name}};
|
||||
{{~if field.gen_ref~}}
|
||||
public {{cs_define_type field.ref_type}} {{field.convention_name}}_Ref => _data.{{field.convention_name}}_Ref;
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
{{~end~}}
|
||||
|
||||
{{~if x.is_map_table||x.is_list_table ~}}
|
||||
private void ResetByteBuf(int readerInex = 0)
|
||||
{
|
||||
if( _buf == null)
|
||||
{
|
||||
if (_buf == null)
|
||||
{
|
||||
_buf = _dataLoader();
|
||||
}
|
||||
}
|
||||
_buf.ReaderIndex = readerInex;
|
||||
}
|
||||
{{~end~}}
|
||||
|
||||
{{~if x.mode != 'ONE'~}}
|
||||
private ByteBuf _buf = null;
|
||||
private Dictionary<string, object> tables;
|
||||
{{~end~}}
|
||||
public void CacheTables(Dictionary<string, object> _tables)
|
||||
{
|
||||
{{~if x.mode == 'ONE'~}}
|
||||
_data.Resolve(_tables);
|
||||
{{~else~}}
|
||||
tables = _tables;
|
||||
{{~end~}}
|
||||
}
|
||||
partial void PostInit();
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
|
||||
{{
|
||||
name = x.name
|
||||
namespace = x.namespace
|
||||
tables = x.tables
|
||||
|
||||
}}
|
||||
namespace {{namespace}}
|
||||
{
|
||||
|
||||
public partial class {{name}}
|
||||
{
|
||||
{{~for table in tables ~}}
|
||||
{{~if table.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{table.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{table.full_name}} {{table.name}} {get; }
|
||||
{{~end~}}
|
||||
|
||||
public {{name}}(System.Func<string, ByteBuf> idxLoader,System.Func<string, ByteBuf> dataLoader)
|
||||
{
|
||||
var tables = new System.Collections.Generic.Dictionary<string, object>();
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}} = new {{table.full_name}}(idxLoader("{{table.output_data_file}}"),"{{table.output_data_file}}",dataLoader);
|
||||
tables.Add("{{table.full_name}}", {{table.name}});
|
||||
{{~end~}}
|
||||
|
||||
PostInit();
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}}.CacheTables(tables);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
partial void PostInit();
|
||||
}
|
||||
|
||||
}
|
@@ -1,95 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Bright.Serialization;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using GameBase;
|
||||
using GameConfig;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 配置加载器
|
||||
/// </summary>
|
||||
public class ConfigSystem : Singleton<ConfigSystem>
|
||||
{
|
||||
private bool _init = false;
|
||||
|
||||
private Tables _tables;
|
||||
|
||||
public Tables Tables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
#if !UNITY_WEBGL
|
||||
_init = true;
|
||||
|
||||
#endif
|
||||
Log.Error("Config not loaded. You need Take LoadAsync at first.");
|
||||
}
|
||||
return _tables;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, TextAsset> _configs = new Dictionary<string, TextAsset>();
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载配置。
|
||||
/// </summary>
|
||||
public async UniTask LoadAsync()
|
||||
{
|
||||
_tables = new Tables();
|
||||
await _tables.LoadAsync(LoadByteBufAsync);
|
||||
_init = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载二进制配置。
|
||||
/// </summary>
|
||||
/// <param name="file">FileName</param>
|
||||
/// <returns>ByteBuf</returns>
|
||||
private async UniTask<ByteBuf> LoadByteBufAsync(string file)
|
||||
{
|
||||
#if false
|
||||
GameTickWatcher gameTickWatcher = new GameTickWatcher();
|
||||
#endif
|
||||
byte[] ret;
|
||||
var location = file;
|
||||
if (_configs.TryGetValue(location, out var config))
|
||||
{
|
||||
ret = config.bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
var textAssets = await GameModule.Resource.LoadAssetAsync<TextAsset>(location, CancellationToken.None);
|
||||
ret = textAssets.bytes;
|
||||
RegisterTextAssets(file, textAssets);
|
||||
}
|
||||
#if false
|
||||
Log.Warning($"LoadByteBuf {file} used time {gameTickWatcher.ElapseTime()}");
|
||||
#endif
|
||||
return new ByteBuf(ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册配置资源。
|
||||
/// </summary>
|
||||
/// <param name="key">资源Key。</param>
|
||||
/// <param name="value">资源实例。</param>
|
||||
/// <returns>注册成功。</returns>
|
||||
private bool RegisterTextAssets(string key, TextAsset value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_configs[key] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,115 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
{{
|
||||
name = x.name
|
||||
parent_def_type = x.parent_def_type
|
||||
export_fields = x.export_fields
|
||||
hierarchy_export_fields = x.hierarchy_export_fields
|
||||
}}
|
||||
|
||||
{{cs_start_name_space_grace x.namespace_with_top_module}}
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Config.BeanBase {{end}}
|
||||
{
|
||||
public {{name}}(ByteBuf _buf) {{if parent_def_type}} : base(_buf) {{end}}
|
||||
{
|
||||
{{~ for field in export_fields ~}}
|
||||
{{cs_deserialize '_buf' field.convention_name field.ctype}}
|
||||
{{~if field.index_field~}}
|
||||
foreach(var _v in {{field.convention_name}})
|
||||
{
|
||||
{{field.convention_name}}_Index.Add(_v.{{field.index_field.convention_name}}, _v);
|
||||
}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public static {{name}} Deserialize{{name}}(ByteBuf _buf)
|
||||
{
|
||||
{{~if x.is_abstract_type~}}
|
||||
switch (_buf.ReadInt())
|
||||
{
|
||||
{{~for child in x.hierarchy_not_abstract_children~}}
|
||||
case {{child.full_name}}.__ID__: return new {{child.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
default: throw new SerializationException();
|
||||
}
|
||||
{{~else~}}
|
||||
return new {{x.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} { get; private set; }
|
||||
{{~if field.index_field~}}
|
||||
public readonly Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}> {{field.convention_name}}_Index = new Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}>();
|
||||
{{~end~}}
|
||||
{{~if field.gen_ref~}}
|
||||
public {{field.cs_ref_validator_define}}
|
||||
{{~end~}}
|
||||
{{~if (gen_datetime_mills field.ctype) ~}}
|
||||
public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L;
|
||||
{{~end~}}
|
||||
{{~if field.gen_text_key~}}
|
||||
public {{cs_define_text_key_field field}} { get; }
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
{{~if !x.is_abstract_type~}}
|
||||
public const int __ID__ = {{x.id}};
|
||||
public override int GetTypeId() => __ID__;
|
||||
{{~end~}}
|
||||
|
||||
public {{x.cs_method_modifier}} void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
{{~if parent_def_type~}}
|
||||
base.Resolve(_tables);
|
||||
{{~end~}}
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.gen_ref~}}
|
||||
{{cs_ref_validator_resolve field}}
|
||||
{{~else if field.has_recursive_ref~}}
|
||||
{{cs_recursive_resolve field '_tables'}}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public {{x.cs_method_modifier}} void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
{{~if parent_def_type~}}
|
||||
base.TranslateText(translator);
|
||||
{{~end~}}
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.gen_text_key~}}
|
||||
{{cs_translate_text field 'translator'}}
|
||||
{{~else if field.has_recursive_text~}}
|
||||
{{cs_recursive_translate_text field 'translator'}}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{{full_name}}{ "
|
||||
{{~for field in hierarchy_export_fields ~}}
|
||||
+ "{{field.convention_name}}:" + {{cs_to_string field.convention_name field.ctype}} + ","
|
||||
{{~end~}}
|
||||
+ "}";
|
||||
}
|
||||
|
||||
partial void PostInit();
|
||||
partial void PostResolve();
|
||||
}
|
||||
|
||||
{{cs_end_name_space_grace x.namespace_with_top_module}}
|
@@ -1,173 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
{{cs_start_name_space_grace x.namespace_with_top_module}}
|
||||
{{
|
||||
name = x.name
|
||||
key_type = x.key_ttype
|
||||
key_type1 = x.key_ttype1
|
||||
key_type2 = x.key_ttype2
|
||||
value_type = x.value_ttype
|
||||
}}
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public partial class {{name}}
|
||||
{
|
||||
{{~if x.is_map_table ~}}
|
||||
private readonly Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> _dataMap;
|
||||
private readonly List<{{cs_define_type value_type}}> _dataList;
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
_dataMap = new Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}>();
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
|
||||
for(int n = _buf.ReadSize() ; n > 0 ; --n)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataList.Add(_v);
|
||||
_dataMap.Add(_v.{{x.index_field.convention_name}}, _v);
|
||||
}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> DataMap => _dataMap;
|
||||
public List<{{cs_define_type value_type}}> DataList => _dataList;
|
||||
|
||||
{{~if value_type.is_dynamic~}}
|
||||
public T GetOrDefaultAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}} => _dataMap.TryGetValue(key, out var v) ? (T)v : null;
|
||||
public T GetAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}} => (T)_dataMap[key];
|
||||
{{~end~}}
|
||||
public {{cs_define_type value_type}} GetOrDefault({{cs_define_type key_type}} key) => _dataMap.TryGetValue(key, out var v) ? v : null;
|
||||
public {{cs_define_type value_type}} Get({{cs_define_type key_type}} key) => _dataMap[key];
|
||||
public {{cs_define_type value_type}} this[{{cs_define_type key_type}} key] => _dataMap[key];
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.Resolve(_tables);
|
||||
}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.TranslateText(translator);
|
||||
}
|
||||
}
|
||||
{{~else if x.is_list_table ~}}
|
||||
private readonly List<{{cs_define_type value_type}}> _dataList;
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
private {{cs_table_union_map_type_name x}} _dataMapUnion;
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
private Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}> _dataMap_{{idx.index_field.name}};
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
|
||||
for(int n = _buf.ReadSize() ; n > 0 ; --n)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataList.Add(_v);
|
||||
}
|
||||
{{~if x.is_union_index~}}
|
||||
_dataMapUnion = new {{cs_table_union_map_type_name x}}();
|
||||
foreach(var _v in _dataList)
|
||||
{
|
||||
_dataMapUnion.Add(({{cs_table_key_list x "_v"}}), _v);
|
||||
}
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
_dataMap_{{idx.index_field.name}} = new Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}>();
|
||||
{{~end~}}
|
||||
foreach(var _v in _dataList)
|
||||
{
|
||||
{{~for idx in x.index_list~}}
|
||||
_dataMap_{{idx.index_field.name}}.Add(_v.{{idx.index_field.convention_name}}, _v);
|
||||
{{~end~}}
|
||||
}
|
||||
{{~end~}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
|
||||
public List<{{cs_define_type value_type}}> DataList => _dataList;
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
public {{cs_define_type value_type}} Get({{cs_table_get_param_def_list x}}) => _dataMapUnion.TryGetValue(({{cs_table_get_param_name_list x}}), out {{cs_define_type value_type}} __v) ? __v : null;
|
||||
{{~else if !x.index_list.empty? ~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
public {{cs_define_type value_type}} GetBy{{idx.index_field.convention_name}}({{cs_define_type idx.type}} key) => _dataMap_{{idx.index_field.name}}.TryGetValue(key, out {{cs_define_type value_type}} __v) ? __v : null;
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.Resolve(_tables);
|
||||
}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.TranslateText(translator);
|
||||
}
|
||||
}
|
||||
{{~else~}}
|
||||
|
||||
private readonly {{cs_define_type value_type}} _data;
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
int n = _buf.ReadSize();
|
||||
if (n != 1) throw new SerializationException("table mode=one, but size != 1");
|
||||
{{cs_deserialize '_buf' '_data' value_type}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
|
||||
{{~ for field in value_type.bean.hierarchy_export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} => _data.{{field.convention_name}};
|
||||
{{~end~}}
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
_data.Resolve(_tables);
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
_data.TranslateText(translator);
|
||||
}
|
||||
|
||||
{{~end~}}
|
||||
|
||||
partial void PostInit();
|
||||
partial void PostResolve();
|
||||
}
|
||||
|
||||
{{cs_end_name_space_grace x.namespace_with_top_module}}
|
@@ -1,53 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
{{
|
||||
name = x.name
|
||||
namespace = x.namespace
|
||||
tables = x.tables
|
||||
}}
|
||||
namespace {{namespace}}
|
||||
{
|
||||
|
||||
public sealed class {{name}}
|
||||
{
|
||||
{{~for table in tables ~}}
|
||||
{{~if table.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{table.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{table.full_name}} {{table.name}} {get; private set; }
|
||||
{{~end~}}
|
||||
|
||||
public {{name}}() { }
|
||||
|
||||
public async UniTask LoadAsync(System.Func<string, UniTask<ByteBuf>> loader)
|
||||
{
|
||||
var tables = new System.Collections.Generic.Dictionary<string, object>();
|
||||
List<UniTask> list = new List<UniTask>();
|
||||
{{~for table in tables ~}}
|
||||
list.Add(UniTask.Create(async () =>
|
||||
{
|
||||
{{table.name}} = new {{table.full_name}}(await loader("{{table.output_data_file}}"));
|
||||
tables.Add("{{table.full_name}}", {{table.name}});
|
||||
}));
|
||||
{{~end~}}
|
||||
|
||||
await UniTask.WhenAll(list);
|
||||
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}}.Resolve(tables);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}}.TranslateText(translator);
|
||||
{{~end~}}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,115 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
{{
|
||||
name = x.name
|
||||
parent_def_type = x.parent_def_type
|
||||
export_fields = x.export_fields
|
||||
hierarchy_export_fields = x.hierarchy_export_fields
|
||||
}}
|
||||
|
||||
{{cs_start_name_space_grace x.namespace_with_top_module}}
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Config.BeanBase {{end}}
|
||||
{
|
||||
public {{name}}(ByteBuf _buf) {{if parent_def_type}} : base(_buf) {{end}}
|
||||
{
|
||||
{{~ for field in export_fields ~}}
|
||||
{{cs_deserialize '_buf' field.convention_name field.ctype}}
|
||||
{{~if field.index_field~}}
|
||||
foreach(var _v in {{field.convention_name}})
|
||||
{
|
||||
{{field.convention_name}}_Index.Add(_v.{{field.index_field.convention_name}}, _v);
|
||||
}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public static {{name}} Deserialize{{name}}(ByteBuf _buf)
|
||||
{
|
||||
{{~if x.is_abstract_type~}}
|
||||
switch (_buf.ReadInt())
|
||||
{
|
||||
{{~for child in x.hierarchy_not_abstract_children~}}
|
||||
case {{child.full_name}}.__ID__: return new {{child.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
default: throw new SerializationException();
|
||||
}
|
||||
{{~else~}}
|
||||
return new {{x.full_name}}(_buf);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} { get; private set; }
|
||||
{{~if field.index_field~}}
|
||||
public readonly Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}> {{field.convention_name}}_Index = new Dictionary<{{cs_define_type field.index_field.ctype}}, {{cs_define_type field.ctype.element_type}}>();
|
||||
{{~end~}}
|
||||
{{~if field.gen_ref~}}
|
||||
public {{field.cs_ref_validator_define}}
|
||||
{{~end~}}
|
||||
{{~if (gen_datetime_mills field.ctype) ~}}
|
||||
public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L;
|
||||
{{~end~}}
|
||||
{{~if field.gen_text_key~}}
|
||||
public {{cs_define_text_key_field field}} { get; }
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
{{~if !x.is_abstract_type~}}
|
||||
public const int __ID__ = {{x.id}};
|
||||
public override int GetTypeId() => __ID__;
|
||||
{{~end~}}
|
||||
|
||||
public {{x.cs_method_modifier}} void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
{{~if parent_def_type~}}
|
||||
base.Resolve(_tables);
|
||||
{{~end~}}
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.gen_ref~}}
|
||||
{{cs_ref_validator_resolve field}}
|
||||
{{~else if field.has_recursive_ref~}}
|
||||
{{cs_recursive_resolve field '_tables'}}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public {{x.cs_method_modifier}} void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
{{~if parent_def_type~}}
|
||||
base.TranslateText(translator);
|
||||
{{~end~}}
|
||||
{{~ for field in export_fields ~}}
|
||||
{{~if field.gen_text_key~}}
|
||||
{{cs_translate_text field 'translator'}}
|
||||
{{~else if field.has_recursive_text~}}
|
||||
{{cs_recursive_translate_text field 'translator'}}
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{{full_name}}{ "
|
||||
{{~for field in hierarchy_export_fields ~}}
|
||||
+ "{{field.convention_name}}:" + {{cs_to_string field.convention_name field.ctype}} + ","
|
||||
{{~end~}}
|
||||
+ "}";
|
||||
}
|
||||
|
||||
partial void PostInit();
|
||||
partial void PostResolve();
|
||||
}
|
||||
|
||||
{{cs_end_name_space_grace x.namespace_with_top_module}}
|
@@ -1,173 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
{{cs_start_name_space_grace x.namespace_with_top_module}}
|
||||
{{
|
||||
name = x.name
|
||||
key_type = x.key_ttype
|
||||
key_type1 = x.key_ttype1
|
||||
key_type2 = x.key_ttype2
|
||||
value_type = x.value_ttype
|
||||
}}
|
||||
{{~if x.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{x.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public partial class {{name}}
|
||||
{
|
||||
{{~if x.is_map_table ~}}
|
||||
private readonly Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> _dataMap;
|
||||
private readonly List<{{cs_define_type value_type}}> _dataList;
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
_dataMap = new Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}>();
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
|
||||
for(int n = _buf.ReadSize() ; n > 0 ; --n)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataList.Add(_v);
|
||||
_dataMap.Add(_v.{{x.index_field.convention_name}}, _v);
|
||||
}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
public Dictionary<{{cs_define_type key_type}}, {{cs_define_type value_type}}> DataMap => _dataMap;
|
||||
public List<{{cs_define_type value_type}}> DataList => _dataList;
|
||||
|
||||
{{~if value_type.is_dynamic~}}
|
||||
public T GetOrDefaultAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}} => _dataMap.TryGetValue(key, out var v) ? (T)v : null;
|
||||
public T GetAs<T>({{cs_define_type key_type}} key) where T : {{cs_define_type value_type}} => (T)_dataMap[key];
|
||||
{{~end~}}
|
||||
public {{cs_define_type value_type}} GetOrDefault({{cs_define_type key_type}} key) => _dataMap.TryGetValue(key, out var v) ? v : null;
|
||||
public {{cs_define_type value_type}} Get({{cs_define_type key_type}} key) => _dataMap[key];
|
||||
public {{cs_define_type value_type}} this[{{cs_define_type key_type}} key] => _dataMap[key];
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.Resolve(_tables);
|
||||
}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.TranslateText(translator);
|
||||
}
|
||||
}
|
||||
{{~else if x.is_list_table ~}}
|
||||
private readonly List<{{cs_define_type value_type}}> _dataList;
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
private {{cs_table_union_map_type_name x}} _dataMapUnion;
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
private Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}> _dataMap_{{idx.index_field.name}};
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
_dataList = new List<{{cs_define_type value_type}}>();
|
||||
|
||||
for(int n = _buf.ReadSize() ; n > 0 ; --n)
|
||||
{
|
||||
{{cs_define_type value_type}} _v;
|
||||
{{cs_deserialize '_buf' '_v' value_type}}
|
||||
_dataList.Add(_v);
|
||||
}
|
||||
{{~if x.is_union_index~}}
|
||||
_dataMapUnion = new {{cs_table_union_map_type_name x}}();
|
||||
foreach(var _v in _dataList)
|
||||
{
|
||||
_dataMapUnion.Add(({{cs_table_key_list x "_v"}}), _v);
|
||||
}
|
||||
{{~else if !x.index_list.empty?~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
_dataMap_{{idx.index_field.name}} = new Dictionary<{{cs_define_type idx.type}}, {{cs_define_type value_type}}>();
|
||||
{{~end~}}
|
||||
foreach(var _v in _dataList)
|
||||
{
|
||||
{{~for idx in x.index_list~}}
|
||||
_dataMap_{{idx.index_field.name}}.Add(_v.{{idx.index_field.convention_name}}, _v);
|
||||
{{~end~}}
|
||||
}
|
||||
{{~end~}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
|
||||
public List<{{cs_define_type value_type}}> DataList => _dataList;
|
||||
|
||||
{{~if x.is_union_index~}}
|
||||
public {{cs_define_type value_type}} Get({{cs_table_get_param_def_list x}}) => _dataMapUnion.TryGetValue(({{cs_table_get_param_name_list x}}), out {{cs_define_type value_type}} __v) ? __v : null;
|
||||
{{~else if !x.index_list.empty? ~}}
|
||||
{{~for idx in x.index_list~}}
|
||||
public {{cs_define_type value_type}} GetBy{{idx.index_field.convention_name}}({{cs_define_type idx.type}} key) => _dataMap_{{idx.index_field.name}}.TryGetValue(key, out {{cs_define_type value_type}} __v) ? __v : null;
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.Resolve(_tables);
|
||||
}
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
foreach(var v in _dataList)
|
||||
{
|
||||
v.TranslateText(translator);
|
||||
}
|
||||
}
|
||||
{{~else~}}
|
||||
|
||||
private readonly {{cs_define_type value_type}} _data;
|
||||
|
||||
public {{name}}(ByteBuf _buf)
|
||||
{
|
||||
int n = _buf.ReadSize();
|
||||
if (n != 1) throw new SerializationException("table mode=one, but size != 1");
|
||||
{{cs_deserialize '_buf' '_data' value_type}}
|
||||
PostInit();
|
||||
}
|
||||
|
||||
|
||||
{{~ for field in value_type.bean.hierarchy_export_fields ~}}
|
||||
{{~if field.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{field.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{cs_define_type field.ctype}} {{field.convention_name}} => _data.{{field.convention_name}};
|
||||
{{~end~}}
|
||||
|
||||
public void Resolve(Dictionary<string, object> _tables)
|
||||
{
|
||||
_data.Resolve(_tables);
|
||||
PostResolve();
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
_data.TranslateText(translator);
|
||||
}
|
||||
|
||||
{{~end~}}
|
||||
|
||||
partial void PostInit();
|
||||
partial void PostResolve();
|
||||
}
|
||||
|
||||
{{cs_end_name_space_grace x.namespace_with_top_module}}
|
@@ -1,46 +0,0 @@
|
||||
using Bright.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
{{
|
||||
name = x.name
|
||||
namespace = x.namespace
|
||||
tables = x.tables
|
||||
}}
|
||||
namespace {{namespace}}
|
||||
{
|
||||
|
||||
public sealed class {{name}}
|
||||
{
|
||||
{{~for table in tables ~}}
|
||||
{{~if table.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{table.escape_comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
public {{table.full_name}} {{table.name}} {get; private set; }
|
||||
{{~end~}}
|
||||
|
||||
public {{name}}() { }
|
||||
|
||||
public async Task LoadAsync(System.Func<string, Task<ByteBuf>> loader)
|
||||
{
|
||||
var tables = new System.Collections.Generic.Dictionary<string, object>();
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}} = new {{table.full_name}}(await loader("{{table.output_data_file}}"));
|
||||
tables.Add("{{table.full_name}}", {{table.name}});
|
||||
{{~end~}}
|
||||
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}}.Resolve(tables);
|
||||
{{~end~}}
|
||||
}
|
||||
|
||||
public void TranslateText(System.Func<string, string, string> translator)
|
||||
{
|
||||
{{~for table in tables ~}}
|
||||
{{table.name}}.TranslateText(translator);
|
||||
{{~end~}}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
<module name="Battle">
|
||||
<enum name="ActorAttrDataType">
|
||||
<var name="None" alias="无效数据" value="0"/>
|
||||
<var name="MaxHp" alias="最大血量" value="1"/>
|
||||
<var name="Attack" alias="攻击力" value="2"/>
|
||||
<var name="PhyDamage" alias="物理伤害" value="3"/>
|
||||
<var name="PhyDef" alias="物理防御" value="4"/>
|
||||
<var name="MagicDamage" alias="法术伤害" value="5"/>
|
||||
<var name="MagicDef" alias="法术防御" value="6"/>
|
||||
<var name="MoveSpeed" alias="移动速度" value="7"/>
|
||||
<var name="AttackSpeed" alias="攻击速度" value="8"/>
|
||||
<var name="Hit" alias="命中率" value="9"/>
|
||||
<var name="Dodge" alias="闪避率" value="10"/>
|
||||
<var name="CriticalAtkRatio" alias="暴击率" value="11"/>
|
||||
<var name="SanValue" alias="San值(疯狂值)" value="12"/>
|
||||
<var name="MaxMp" alias="最大MP" value="13"/>
|
||||
|
||||
<var name="PhyDamageRatio" alias="物理伤害倍率" value="14"/>
|
||||
<var name="MagicDamageRatio" alias="魔法伤害倍率" value="15"/>
|
||||
<var name="CriticalRatio" alias="暴击倍率" value="16"/>
|
||||
<var name="CriticalReduce" alias="暴击减免" value="17"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ActorAttrAddType">
|
||||
<var name="NONE" alias="无效数据" value="0"/>
|
||||
<var name="ABSOLUTE_VAL" alias="加法计算" value="1"/>
|
||||
<var name="SUM_PERCENT_VAL" alias="多个项结果累加,然后对加法做乘法" value="2"/>
|
||||
<var name="MUL_PERCENT_VAL" alias="每一项都是对最终结果做乘法" value="3"/>
|
||||
</enum>
|
||||
|
||||
<bean name="ResAttrImpactData" sep="," parent="">
|
||||
<var name="DataType" type="ActorAttrDataType"/>
|
||||
<var name="AddType" type="ActorAttrAddType"/>
|
||||
<var name="Value" type="float"/>
|
||||
</bean>
|
||||
</module>
|
@@ -1,68 +0,0 @@
|
||||
<module name="Battle">
|
||||
<enum name="BuffTimeType">
|
||||
<var name="BUFF_TIME_DURING" alias="指定持续时间" value="0"/>
|
||||
<var name="BUFF_TIME_INFINIT" alias="无尽时间" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="BuffReplaceType">
|
||||
<var name="BUFF_REPLACE_INSTEAD" alias="更新时间范围" value="0"/>
|
||||
<var name="BUFF_REPLACE_FORBIT" alias="不允许叠加" value="1"/>
|
||||
<var name="BUFF_REPLACE_ADD_TIME" alias="累加时间范围" value="2"/>
|
||||
<var name="BUFF_REPLACE_ADD_ATTR" alias="叠加数值" value="3"/>
|
||||
<var name="BUFF_REPLACE_TYPE_COUNT" alias="叠加种类" value="4"/>
|
||||
</enum>
|
||||
|
||||
<enum name="BuffStateID">
|
||||
<var name="BUFF_STATE_NONE" alias="无状态" value="0"/>
|
||||
<var name="BUFF_STATE_STUN" alias="眩晕状态" value="1"/>
|
||||
<var name="BUFF_STATE_UNDEAD" alias="无敌状态" value="2"/>
|
||||
<var name="BUFF_STATE_INVISIBLE" alias="隐身状态" value="3"/>
|
||||
<var name="BUFF_STATE_BIGGER" alias="体形变大" value="4"/>
|
||||
<var name="BUFF_STATE_NO_MOVE" alias="定身,不能移动" value="5"/>
|
||||
<var name="BUFF_STATE_NO_SKILL" alias="沉默,不能放技能" value="6"/>
|
||||
<var name="BUFF_STATE_SLEEP" alias="昏睡" value="7"/>
|
||||
<var name="BUFF_STATE_FORCE_COLLIDER" alias="强制开启阻挡" value="8"/>
|
||||
<var name="BUFF_STATE_IGNORE_COLLIDER" alias="无视阻挡" value="9"/>
|
||||
<var name="BUFF_STATE_MAX" alias="最大状态" value="10"/>
|
||||
</enum>
|
||||
|
||||
<enum name="BuffResultType">
|
||||
<var name="BUFF_RESULT_NONE" alias="无" value="0"/>
|
||||
<var name="BUFF_RESULT_PHY_ATK_UP" alias="物理攻击提升" value="1"/>
|
||||
<var name="BUFF_RESULT_PHY_ATK_DOWN" alias="物理攻击降低" value="2"/>
|
||||
<var name="BUFF_RESULT_PHY_DEF_UP" alias="物理防御提升" value="3"/>
|
||||
<var name="BUFF_RESULT_PHY_DEF_DOWN" alias="物理防御降低" value="4"/>
|
||||
<var name="BUFF_RESULT_PHY_HIT_UP" alias="物理命中提升" value="5"/>
|
||||
<var name="BUFF_RESULT_PHY_HIT_DOWN" alias="物理命中降低" value="6"/>
|
||||
<var name="BUFF_RESULT_PHY_LOSE_HP" alias="物理持续掉血" value="7"/>
|
||||
|
||||
<var name="BUFF_RESULT_MAG_ATK_UP" alias="法术攻击提升" value="8"/>
|
||||
<var name="BUFF_RESULT_MAG_ATK_DOWN" alias="法术攻击降低" value="9"/>
|
||||
<var name="BUFF_RESULT_MAG_DEF_UP" alias="法术防御提升" value="10"/>
|
||||
<var name="BUFF_RESULT_MAG_DEF_DOWN" alias="法术防御降低" value="11"/>
|
||||
<var name="BUFF_RESULT_MAG_HIT_UP" alias="法术命中提升" value="12"/>
|
||||
<var name="BUFF_RESULT_MAG_HIT_DOWN" alias="法术命中降低" value="13"/>
|
||||
<var name="BUFF_RESULT_MAG_LOSE_HP" alias="法术持续掉血" value="14"/>
|
||||
|
||||
<var name="BUFF_RESULT_CIRT_UP" alias="暴击率提升" value="15"/>
|
||||
<var name="BUFF_RESULT_CIRT_DOWN" alias="暴击率降低" value="16"/>
|
||||
<var name="BUFF_RESULT_CIRT_VALUE_UP" alias="暴击倍率提升" value="17"/>
|
||||
<var name="BUFF_RESULT_CIRT_VALUE_DOWN" alias="暴击倍率降低" value="18"/>
|
||||
|
||||
<var name="BUFF_RESULT_MOVE_SPEED_UP" alias="移速提升" value="19"/>
|
||||
<var name="BUFF_RESULT_MOVE_SPEED_DOWN" alias="移速降低" value="20"/>
|
||||
</enum>
|
||||
|
||||
<bean name="BuffTriggleState" sep="," parent="">
|
||||
<var name="StateID" type="BuffStateID"/>
|
||||
<var name="StateParam" type="float"/>
|
||||
</bean>
|
||||
|
||||
<bean name="BuffDotTickConfig" sep="," parent="">
|
||||
<!-- 触发间隔,如果为0, 则只加一次 -->
|
||||
<var name="TickTime" type="float"/>
|
||||
<!-- 1增加buff的时候立刻触发,否则等待TickTime后再触发 -->
|
||||
<var name="TickWhenAdd" type="int"/>
|
||||
</bean>
|
||||
|
||||
</module>
|
@@ -1,25 +0,0 @@
|
||||
<module name="Battle">
|
||||
<enum name="SkillMagicType"> 技能元素类型
|
||||
<var name="SKILL_TYPE_NONE" alias="无类型" value="0"/>
|
||||
<var name="SKILL_TYPE_DMG_PHY" alias="物理伤害属性" value="1"/>
|
||||
<var name="SKILL_TYPE_DMG_MAGIC" alias="魔法伤害属性" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SkillAttrDamageType"> 伤害类型
|
||||
<var name="ATTR_TYPE_NONE" alias="无数值" value="0"/>
|
||||
<var name="ATTR_TYPE_DMG_WEAPON" alias="按释放者的伤害类型*X%+固定值计算,目标有防御计算" value="1"/>
|
||||
<var name="ATTR_TYPE_DMG_NO_DEFEND" alias="按释放者的伤害类型*X%+固定值计算(无视目标的防御)" value="2"/>
|
||||
<var name="ATTR_TYPE_DMG_TARGET_HP_NO_DEFEND" alias="按受击者的气血上限*X%+固定值计算(无视目标的防御)" value="3"/>
|
||||
<var name="ATTR_TYPE_HP_AS_ATK" alias="按释放者的攻击类型*X%+固定值计算,恢复当前生命" value="4"/>
|
||||
<var name="ATTR_TYPE_HP_RATIO" alias="按受击者的HP上限*X%+固定值计算,恢复当前生命" value="5"/>
|
||||
</enum>
|
||||
|
||||
<bean name="SkillAttrDamageData" sep="," parent="">
|
||||
<var name="MagicType" type="SkillMagicType"/>
|
||||
<var name="AttrType" type="SkillAttrDamageType"/>
|
||||
<var name="Param1" type="float"/>
|
||||
<var name="Param2" type="float"/>
|
||||
<var name="Param3" type="float"/>
|
||||
<var name="MaxLimit" type="float"/>
|
||||
</bean>
|
||||
</module>
|
@@ -1,23 +0,0 @@
|
||||
<root>
|
||||
|
||||
<topmodule name="GameConfig"/>
|
||||
|
||||
<externalselector name="unity"/>
|
||||
|
||||
<patch name="cn"/>
|
||||
<patch name="en"/>
|
||||
|
||||
<group name="c,client" default="1"/> client
|
||||
<group name="s,server" default="1"/> server
|
||||
<group name="e" default="1"/> editor
|
||||
|
||||
<import name="."/>
|
||||
|
||||
<importexcel name="__tables__.xlsx" type="table"/> 相对data目录
|
||||
<importexcel name="__enums__.xlsx" type="enum"/>相对data目录
|
||||
<importexcel name="__beans__.xlsx" type="bean"/>相对data目录
|
||||
|
||||
<service name="server" manager="Tables" group="s"/>
|
||||
<service name="client" manager="Tables" group="c"/>
|
||||
<service name="all" manager="Tables" group="c,s,e"/>
|
||||
</root>
|
@@ -1,4 +1,4 @@
|
||||
using Bright.Serialization;
|
||||
using Luban;
|
||||
using GameBase;
|
||||
using GameConfig;
|
||||
using TEngine;
|
||||
@@ -21,6 +21,7 @@ public class ConfigSystem : Singleton<ConfigSystem>
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
return _tables;
|
||||
}
|
||||
}
|
||||
@@ -41,8 +42,9 @@ public class ConfigSystem : Singleton<ConfigSystem>
|
||||
/// <returns>ByteBuf</returns>
|
||||
private ByteBuf LoadByteBuf(string file)
|
||||
{
|
||||
var textAssets = GameModule.Resource.LoadAsset<TextAsset>(file);
|
||||
byte[] ret = textAssets.bytes;
|
||||
return new ByteBuf(ret);
|
||||
TextAsset textAsset = GameModule.Resource.LoadAsset<TextAsset>(file);
|
||||
byte[] bytes = textAsset.bytes;
|
||||
GameModule.Resource.UnloadAsset(textAsset);
|
||||
return new ByteBuf(bytes);
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using Luban;
|
||||
|
||||
{{namespace_with_grace_begin __namespace}}
|
||||
public partial class {{__name}}
|
||||
{
|
||||
#region The Tables
|
||||
|
||||
{{~for table in __tables ~}}
|
||||
{{~if table.comment != '' ~}}
|
||||
/// <summary>
|
||||
/// {{escape_comment table.comment}}
|
||||
/// </summary>
|
||||
{{~end~}}
|
||||
private {{table.full_name}} m_{{table.name}};
|
||||
public {{table.full_name}} {{format_property_name __code_style table.name}}
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_{{table.name}} == null)
|
||||
{
|
||||
m_{{table.name}} = new {{table.full_name}}(defaultLoader("{{table.output_data_file}}"));
|
||||
m_{{table.name}}.ResolveRef(this);
|
||||
}
|
||||
return m_{{table.name}};
|
||||
}
|
||||
set
|
||||
{
|
||||
m_{{table.name}} = value;
|
||||
m_{{table.name}}.ResolveRef(this);
|
||||
}
|
||||
}
|
||||
{{~end~}}
|
||||
|
||||
#endregion
|
||||
|
||||
System.Func<string, ByteBuf> defaultLoader;
|
||||
|
||||
public {{__name}}(System.Func<string, ByteBuf> loader)
|
||||
{
|
||||
SetDefaultLoader(loader);
|
||||
Init();
|
||||
}
|
||||
|
||||
public void SetDefaultLoader(System.Func<string, ByteBuf> loader)
|
||||
{
|
||||
defaultLoader = null;
|
||||
defaultLoader = loader;
|
||||
}
|
||||
|
||||
//public partial void Init();
|
||||
|
||||
public void Init(){}
|
||||
}
|
||||
|
||||
{{namespace_with_grace_end __namespace}}
|
BIN
Configs/GameConfig/Datas/__beans__.xlsx
Normal file
BIN
Configs/GameConfig/Datas/__enums__.xlsx
Normal file
BIN
Configs/GameConfig/Datas/__tables__.xlsx
Normal file
BIN
Configs/GameConfig/Datas/item.xlsx
Normal file
17
Configs/GameConfig/Defines/builtin.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<module name="">
|
||||
<bean name="vector2" valueType="1" sep=",">
|
||||
<var name="x" type="float"/>
|
||||
<var name="y" type="float"/>
|
||||
</bean>
|
||||
<bean name="vector3" valueType="1" sep=",">
|
||||
<var name="x" type="float"/>
|
||||
<var name="y" type="float"/>
|
||||
<var name="z" type="float"/>
|
||||
</bean>
|
||||
<bean name="vector4" valueType="1" sep=",">
|
||||
<var name="x" type="float"/>
|
||||
<var name="y" type="float"/>
|
||||
<var name="z" type="float"/>
|
||||
<var name="w" type="float"/>
|
||||
</bean>
|
||||
</module>
|
20
Configs/GameConfig/gen_code_bin_to_project.bat
Normal file
@@ -0,0 +1,20 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../..
|
||||
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
|
||||
set CONF_ROOT=.
|
||||
set DATA_OUTPATH=%WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/
|
||||
set CODE_OUTPATH=%WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig/
|
||||
|
||||
xcopy /s /e /i /y "%CONF_ROOT%\CustomTemplate\ConfigSystem.cs" "%WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs"
|
||||
|
||||
dotnet %LUBAN_DLL% ^
|
||||
-t client ^
|
||||
-c cs-bin ^
|
||||
-d bin^
|
||||
--conf %CONF_ROOT%\luban.conf ^
|
||||
-x outputCodeDir=%CODE_OUTPATH% ^
|
||||
-x outputDataDir=%DATA_OUTPATH%
|
||||
pause
|
||||
|
24
Configs/GameConfig/gen_code_bin_to_project.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
echo "当前目录: $(pwd)"
|
||||
|
||||
export WORKSPACE="$(realpath ../../)"
|
||||
export LUBAN_DLL="${WORKSPACE}/Tools/Luban/Luban.dll"
|
||||
export CONF_ROOT="$(pwd)"
|
||||
export DATA_OUTPATH="${WORKSPACE}/UnityProject/Assets/AssetRaw/Configs/bytes/"
|
||||
export CODE_OUTPATH="${WORKSPACE}/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig/"
|
||||
|
||||
cp -R "${CONF_ROOT}/CustomTemplate/ConfigSystem.cs" \
|
||||
"${WORKSPACE}/UnityProject/Assets/GameScripts/HotFix/GameProto/ConfigSystem.cs"
|
||||
|
||||
dotnet "${LUBAN_DLL}" \
|
||||
-t client \
|
||||
-c cs-bin \
|
||||
-d bin \
|
||||
--conf "${CONF_ROOT}/luban.conf" \
|
||||
-x outputCodeDir="${CODE_OUTPATH}" \
|
||||
-x outputDataDir="${DATA_OUTPATH}"
|
||||
|
||||
echo "操作完成,按任意键退出..."
|
||||
read -k1
|
21
Configs/GameConfig/gen_code_bin_to_project_lazyload.bat
Normal file
@@ -0,0 +1,21 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../..
|
||||
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
|
||||
set CONF_ROOT=.
|
||||
set DATA_OUTPATH=%WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/
|
||||
set CODE_OUTPATH=%WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig/
|
||||
|
||||
xcopy /s /e /i /y "%CONF_ROOT%\CustomTemplate\ConfigSystem.cs" "%WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs"
|
||||
|
||||
dotnet %LUBAN_DLL% ^
|
||||
-t client ^
|
||||
-c cs-bin ^
|
||||
-d bin^
|
||||
--conf %CONF_ROOT%\luban.conf ^
|
||||
--customTemplateDir %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_LazyLoad ^
|
||||
-x outputCodeDir=%CODE_OUTPATH% ^
|
||||
-x outputDataDir=%DATA_OUTPATH%
|
||||
pause
|
||||
|
25
Configs/GameConfig/gen_code_bin_to_project_lazyload.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
echo "当前目录: $(pwd)"
|
||||
|
||||
export WORKSPACE="$(realpath ../../)"
|
||||
export LUBAN_DLL="${WORKSPACE}/Tools/Luban/Luban.dll"
|
||||
export CONF_ROOT="$(pwd)"
|
||||
export DATA_OUTPATH="${WORKSPACE}/UnityProject/Assets/AssetRaw/Configs/bytes/"
|
||||
export CODE_OUTPATH="${WORKSPACE}/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig/"
|
||||
|
||||
cp -R "${CONF_ROOT}/CustomTemplate/ConfigSystem.cs" \
|
||||
"${WORKSPACE}/UnityProject/Assets/GameScripts/HotFix/GameProto/ConfigSystem.cs"
|
||||
|
||||
dotnet "${LUBAN_DLL}" \
|
||||
-t client \
|
||||
-c cs-bin \
|
||||
-d bin \
|
||||
--conf "${CONF_ROOT}/luban.conf" \
|
||||
--customTemplateDir "${CONF_ROOT}/CustomTemplate/CustomTemplate_Client_LazyLoad" \
|
||||
-x outputCodeDir="${CODE_OUTPATH}" \
|
||||
-x outputDataDir="${DATA_OUTPATH}"
|
||||
|
||||
echo "操作完成,按任意键退出..."
|
||||
read -k1
|
18
Configs/GameConfig/gen_code_bin_to_server.bat
Normal file
@@ -0,0 +1,18 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../../
|
||||
set LUBAN_DLL=%WORKSPACE%/Tools/Luban/Luban.dll
|
||||
set CONF_ROOT=.
|
||||
set DATA_OUTPATH=%WORKSPACE%/Server/GameConfig
|
||||
set CODE_OUTPATH=%WORKSPACE%/Server/Hotfix/Config/GameConfig
|
||||
|
||||
dotnet %LUBAN_DLL% ^
|
||||
-t server^
|
||||
-c cs-bin ^
|
||||
-d bin^
|
||||
--conf %CONF_ROOT%\luban.conf ^
|
||||
-x outputCodeDir=%CODE_OUTPATH% ^
|
||||
-x outputDataDir=%DATA_OUTPATH%
|
||||
pause
|
||||
|
21
Configs/GameConfig/gen_code_bin_to_server.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
echo "当前目录: $(pwd)"
|
||||
|
||||
export WORKSPACE="$(realpath ../../)"
|
||||
export LUBAN_DLL="${WORKSPACE}/Tools/Luban/Luban.dll"
|
||||
export CONF_ROOT="$(pwd)"
|
||||
export DATA_OUTPATH="${WORKSPACE}/Server/GameConfig"
|
||||
export CODE_OUTPATH="${WORKSPACE}/Server/Hotfix/Config/GameConfig"
|
||||
|
||||
dotnet "${LUBAN_DLL}" \
|
||||
-t server \
|
||||
-c cs-bin \
|
||||
-d bin \
|
||||
--conf "${CONF_ROOT}/luban.conf" \
|
||||
-x outputCodeDir="${CODE_OUTPATH}" \
|
||||
-x outputDataDir="${DATA_OUTPATH}"
|
||||
|
||||
echo "操作完成,按任意键退出..."
|
||||
read -k1
|
22
Configs/GameConfig/luban.conf
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"groups":
|
||||
[
|
||||
{"names":["c"], "default":true},
|
||||
{"names":["s"], "default":true},
|
||||
{"names":["e"], "default":true}
|
||||
],
|
||||
"schemaFiles":
|
||||
[
|
||||
{"fileName":"Defines", "type":""},
|
||||
{"fileName":"Datas/__tables__.xlsx", "type":"table"},
|
||||
{"fileName":"Datas/__beans__.xlsx", "type":"bean"},
|
||||
{"fileName":"Datas/__enums__.xlsx", "type":"enum"}
|
||||
],
|
||||
"dataDir": "Datas",
|
||||
"targets":
|
||||
[
|
||||
{"name":"server", "manager":"Tables", "groups":["s"], "topModule":"GameConfig"},
|
||||
{"name":"client", "manager":"Tables", "groups":["c"], "topModule":"GameConfig"},
|
||||
{"name":"all", "manager":"Tables", "groups":["c,s,e"], "topModule":"GameConfig"}
|
||||
]
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
cd /d %~dp0
|
||||
set WORKSPACE=..
|
||||
|
||||
set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
|
||||
set CONF_ROOT=%WORKSPACE%\Configs
|
||||
set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
|
||||
set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client
|
||||
|
||||
xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
|
||||
|
||||
%GEN_CLIENT% -j cfg --^
|
||||
-d %CONF_ROOT%\Defines\__root__.xml ^
|
||||
--input_data_dir %CONF_ROOT%\Excels^
|
||||
--output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
|
||||
--output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
|
||||
--gen_types code_cs_unity_bin,data_bin ^
|
||||
-s client
|
||||
|
||||
echo ======== 生成配置文件结束 ========
|
||||
|
||||
pause
|
@@ -1,40 +0,0 @@
|
||||
cd /d %~dp0
|
||||
set WORKSPACE=..
|
||||
|
||||
set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
|
||||
set CONF_ROOT=%WORKSPACE%\Configs
|
||||
set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
|
||||
set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client_LazyLoad
|
||||
|
||||
xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
|
||||
|
||||
%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_LazyLoad -j cfg --^
|
||||
-d %CONF_ROOT%\Defines\__root__.xml ^
|
||||
--input_data_dir %CONF_ROOT%\Excels^
|
||||
--output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
|
||||
--output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
|
||||
--gen_types data_bin ^
|
||||
-s client
|
||||
|
||||
%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_LazyLoad -j cfg --^
|
||||
-d %CONF_ROOT%\Defines\__root__.xml ^
|
||||
--input_data_dir %CONF_ROOT%\Excels^
|
||||
--output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
|
||||
--output_data_dir ..\GenerateDatas\bidx ^
|
||||
--gen_types code_cs_unity_bin,data_bidx ^
|
||||
-s client
|
||||
|
||||
echo ======== 生成配置文件结束 ========
|
||||
set WORKSPACE=..
|
||||
|
||||
set "prefix=Idx_"
|
||||
|
||||
for %%a in (%DATA_OUTPUT%\bidx\*) do (
|
||||
ren "%%a" "Idx_%%~nxa"
|
||||
)
|
||||
|
||||
echo ======== 所有文件已添加前缀 ========
|
||||
|
||||
xcopy %DATA_OUTPUT%\bidx\ %WORKSPACE%\UnityProject\Assets\AssetRaw\Configs\bidx\ /s /e /i /y
|
||||
|
||||
pause
|
@@ -1,21 +0,0 @@
|
||||
cd /d %~dp0
|
||||
set WORKSPACE=..
|
||||
|
||||
set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
|
||||
set CONF_ROOT=%WORKSPACE%\Configs
|
||||
set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
|
||||
set CUSTOM_TEMP=%WORKSPACE%\Configs\CustomTemplate\CustomTemplate_Client_UniTask
|
||||
|
||||
xcopy %CUSTOM_TEMP%\ConfigSystem.cs %WORKSPACE%\UnityProject\Assets\GameScripts\HotFix\GameProto\ConfigSystem.cs /s /e /i /y
|
||||
|
||||
%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Client_UniTask -j cfg --^
|
||||
-d %CONF_ROOT%\Defines\__root__.xml ^
|
||||
--input_data_dir %CONF_ROOT%\Excels^
|
||||
--output_code_dir %WORKSPACE%/UnityProject/Assets/GameScripts/HotFix/GameProto/GameConfig ^
|
||||
--output_data_dir %WORKSPACE%/UnityProject/Assets/AssetRaw/Configs/bytes/ ^
|
||||
--gen_types code_cs_unity_bin,data_bin ^
|
||||
-s client
|
||||
|
||||
echo ======== 生成配置文件结束 ========
|
||||
|
||||
pause
|
@@ -1,18 +0,0 @@
|
||||
cd /d %~dp0
|
||||
set WORKSPACE=..
|
||||
|
||||
set GEN_CLIENT=%WORKSPACE%\Tools\Luban.ClientServer\Luban.ClientServer.exe
|
||||
set CONF_ROOT=%WORKSPACE%\Configs
|
||||
set DATA_OUTPUT=%ROOT_PATH%..\GenerateDatas
|
||||
|
||||
%GEN_CLIENT% --template_search_path %CONF_ROOT%\CustomTemplate\CustomTemplate_Server_Task -j cfg --^
|
||||
-d %CONF_ROOT%\Defines\__root__.xml ^
|
||||
--input_data_dir %CONF_ROOT%\Excels^
|
||||
--output_code_dir %WORKSPACE%/DotNet/Logic/src/Config/GameConfig ^
|
||||
--output_data_dir ..\DotNet\Config\GameConfig ^
|
||||
--gen_types code_cs_bin,data_bin ^
|
||||
-s server
|
||||
|
||||
echo ======== 生成配置文件结束 ========
|
||||
|
||||
pause
|
52
README.md
@@ -33,9 +33,6 @@
|
||||
|
||||
#### TEngine是一个简单(新手友好开箱即用)且强大的Unity框架全平台解决方案,对于需要一套上手快、文档清晰、高性能且可拓展性极强的商业级解决方案的开发者或者团队来说是一个很好的选择。
|
||||
|
||||
|
||||
## <a href="http://1.12.241.46:5000/"><strong>文档快速入门 »</strong></a>
|
||||
|
||||
## 文档快速预览 - 5分钟
|
||||
* [全平台跑通示意](Books/99-各平台运行RunAble.md): 全平台跑通示意。
|
||||
* [01_介绍](Books/0-介绍.md): 简单介绍。
|
||||
@@ -46,49 +43,54 @@
|
||||
* [06_对象池模块](Books/3-4-%E5%AF%B9%E8%B1%A1%E6%B1%A0%E6%A8%A1%E5%9D%97.md): 展示对象池模块概览。
|
||||
* [07_配置表模块](Books/3-6-%E9%85%8D%E7%BD%AE%E8%A1%A8%E6%A8%A1%E5%9D%97.md): 展示配置表模块概览。
|
||||
* [08_流程模块](Books/3-7-%E6%B5%81%E7%A8%8B%E6%A8%A1%E5%9D%97.md): 展示商业化流程模块。
|
||||
* [09_UI模块](Books/3-5-UI模块.md): 展示商业化UI模块。
|
||||
|
||||
|
||||
## <strong>为什么要使用TEngine
|
||||
0. 开箱即用5分钟即可上手整套开发流程,代码整洁,思路清晰,功能强大。高内聚低耦合。您可以很轻易的把您不需要的模块进行移除替换。
|
||||
1. 严格按照商业要求使用次世代的HybridClr进行热更新、最佳的Luban配置表(TEngine支持懒加载、异步加载、同步加载配置。)、百万DAU游戏验证过的YooAsset资源框架(框架管理资源引用与释放。),全平台热更新流程已跑通。
|
||||
2. 严格按照商业化流程执行的热更新、商业化的UI开发流程、以及资源管理等等,设计并实现了YooAsset资源自动释放、支持LRU、ARC严格管理资源内存。
|
||||
3. C#双端解决方案,服务器使用Fantasy,是一套源于ETServer,但极为简洁,性能更强,更好上手的一套商业级服务器框架。
|
||||
4. 支持全平台,已有项目使用TEngine上架Steam、Wechat-minigame、AppStore。
|
||||
3. 支持全平台,已有项目使用TEngine上架Steam、Wechat-minigame、AppStore。
|
||||
|
||||
## <strong>资源重要拓展概念
|
||||
* AssetReference (资源引用标识) 通用加载资源的时候绑定一个引用标识使你无需关心手动Dispose资源句柄。
|
||||
## <strong>最新的Demo飞机大战位于demo分支
|
||||
|
||||
* AssetGroup(资源组数据)进行资源分组绑定管理内存中的生命周期资源生命周期托管给资源组的根节点进行Dispose。
|
||||
## <strong>服务器相关
|
||||
TEngine本身为纯净的客户端。不强绑定任何服务器。但是个人开发以及中小型公司开发双端则推荐C#服务器。
|
||||
|
||||
* LruCacheTable (Least Recently Used Cache缓存表)
|
||||
|
||||
* ArcCacheTable (Adaptive Replacement Cache缓存表)
|
||||
|
||||
## <strong>为什么服务器使用C#
|
||||
Net Core现在已经更新到了8.0的版本,在性能和设计上其实是远超JAVA和GO。在JAVAER还在为JVM更新和添加更多功能时,其实他们已经被国内大环境所包围了,看不到.Net Core的性能之强,组件化的结构。国内大环境是JAVA和GO的天下这个不可否认,但是国外C#也确实很多。其实.Net Core最大的问题是大多数自己人都不知道他的优点(AOT、JIT混合编译、热重载等等),甚至很多守旧派抵制core。GO喜欢吹性能,但其实目前来看,除了协程的轻量级,大多数性能测试其实不如JAVA和.Net。简单可以说出了C++的性能以外,Net Core其实都打得过。
|
||||
<strong>当然作为商业级解决方案服务器的耦合度也极低,如果不喜欢您也可以很轻松直接移除替换成你的服务器。</strong>
|
||||
|
||||
需要服务器可以合并<a href="https://github.com/ALEXTANGXIAO/GameNetty"><strong>GameNetty</strong></a>过来,或者分支Fantasy为接好的带有Fantasy服务器的双端分支。
|
||||
|
||||
## <strong>项目结构概览
|
||||
```
|
||||
Assets
|
||||
├── AssetArt // 美术资源目录
|
||||
│ └── Atlas // 自动生成图集目录
|
||||
├── AssetRaw // 热更资源目录
|
||||
├── Atlas // 自动生成图集目录
|
||||
│ ├── UIRaw // UI图片目录
|
||||
│ │ ├── Atlas // 需要自动生成图集的UI素材目录
|
||||
│ │ └── Raw // 不需要自动生成图集的UI素材目录
|
||||
├── Editor // 编辑器脚本目录
|
||||
├── HybridCLRData // hybridclr相关目录
|
||||
├── Scenes // 主场景目录
|
||||
├── TEngine // 框架核心目录
|
||||
└── GameScripts // 程序集目录
|
||||
├── Editor // 编辑器程序集
|
||||
├── Main // 主程序程序集(启动器与流程)
|
||||
└── HotFix // 游戏热更程序集目录 [Folder]
|
||||
├── GameBase // 游戏基础框架程序集 [Dll]
|
||||
├── GameProto // 游戏配置协议程序集 [Dll]
|
||||
├── BattleCore // 游戏核心战斗程序集 [Dll]
|
||||
├── GameProto // 游戏配置协议程序集 [Dll]
|
||||
└── GameLogic // 游戏业务逻辑程序集 [Dll]
|
||||
├── GameApp.cs // 热更主入口
|
||||
└── GameApp_RegisterSystem.cs // 热更主入口注册系统
|
||||
└── GameApp_RegisterSystem.cs // 热更主入口注册系统
|
||||
|
||||
|
||||
TEngine
|
||||
├── Editor // TEngine编辑器核心代码
|
||||
└── Runtime // TEngine运行时核心代码
|
||||
```
|
||||
|
||||
- 必要:项目使用了以下第三方插件,请自行购买导入:
|
||||
- /Unity/Assets/Plugins/Sirenix
|
||||
- /UnityProject/Assets/Plugins/Sirenix
|
||||
|
||||
---
|
||||
## <strong>优质开源项目推荐
|
||||
@@ -99,7 +101,11 @@ Assets
|
||||
|
||||
#### <a href="https://github.com/focus-creative-games/hybridclr"><strong>HybridCLR</strong></a> - 特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案
|
||||
|
||||
#### <a href="https://github.com/qq362946/Fantasy"><strong>Fantasy</strong></a> - Fantasy是一套源于ETServer但极为简洁,性能更强,更好上手的一套商业级服务器框架。
|
||||
#### <a href="https://github.com/qq362946/Fantasy"><strong>Fantasy</strong></a> - Fantasy是一套源于ETServer但极为简洁,更好上手的一套商业级服务器框架。
|
||||
|
||||
## <strong>交流群
|
||||
### <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=MzOcQIzGVLQ5AC5LHaqqA3h_F6lZ_DX4&authKey=LctqAWGHkJ7voQvuj1oaSe5tsGrc1XmQG3U4QniieGUlxY3lC7FtDIpEvPOX0vT8&noverify=0&group_code=862987645">群 号:862987645 </strong></a>
|
||||
#### <a href="https://github.com/ALEXTANGXIAO/GameNetty"><strong>GameNetty</strong></a> - GameNetty是一套源于ETServer,首次拆分最新的ET8.1的前后端解决方案(包),客户端最精简大约750k,完美做成包的形式,几乎零成本 无侵入的嵌入进你的框架。
|
||||
|
||||
|
||||
## <strong>Buy me a 奶茶.
|
||||
|
||||
[您的赞助会让我们做得更快更好,如果觉得TEngine对您有帮助,不妨请我可爱的女儿买杯奶茶吧~](Books/Donate.md)
|
||||
|
3
Tools/FileServer/instal.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
npm install yumu-static-server -g
|
3
Tools/FileServer/start.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
server -p 8081 -cors
|
@@ -1 +0,0 @@
|
||||
目前使用luban-classic,请自行导入
|
1
Tools/Luban/about.txt
Normal file
@@ -0,0 +1 @@
|
||||
使用luban-next, 请前往Tools/build-luban编译或者自行导入
|
1
UnityProject/.gitignore
vendored
@@ -90,6 +90,7 @@ Sandbox/
|
||||
# [Aa]ssets/Plugins/Sirenix.meta
|
||||
|
||||
#YooAssets
|
||||
package/
|
||||
yoo/
|
||||
[Aa]ssets/TEngine/AssetSetting/Resources/BuiltinFileManifest.asset
|
||||
[Aa]ssets/TEngine/AssetSetting/Resources/BuiltinFileManifest.asset.meta
|
@@ -1,14 +1,13 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!612988286 &4096168566840163508
|
||||
SpriteAtlasAsset:
|
||||
--- !u!687078895 &4343727234628468602
|
||||
SpriteAtlas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UIRaw_Atlas_Common
|
||||
m_MasterAtlas: {fileID: 0}
|
||||
m_ImporterData:
|
||||
m_EditorData:
|
||||
serializedVersion: 2
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
@@ -34,6 +33,30 @@ SpriteAtlasAsset:
|
||||
m_Overridden: 1
|
||||
m_AndroidETC2FallbackOverride: 0
|
||||
m_ForceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
m_BuildTarget: Android
|
||||
m_MaxTextureSize: 2048
|
||||
m_ResizeAlgorithm: 0
|
||||
m_TextureFormat: 50
|
||||
m_TextureCompression: 1
|
||||
m_CompressionQuality: 100
|
||||
m_CrunchedCompression: 0
|
||||
m_AllowsAlphaSplitting: 0
|
||||
m_Overridden: 1
|
||||
m_AndroidETC2FallbackOverride: 0
|
||||
m_ForceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
m_BuildTarget: WebGL
|
||||
m_MaxTextureSize: 2048
|
||||
m_ResizeAlgorithm: 0
|
||||
m_TextureFormat: 50
|
||||
m_TextureCompression: 1
|
||||
m_CompressionQuality: 50
|
||||
m_CrunchedCompression: 0
|
||||
m_AllowsAlphaSplitting: 0
|
||||
m_Overridden: 1
|
||||
m_AndroidETC2FallbackOverride: 0
|
||||
m_ForceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
packingSettings:
|
||||
serializedVersion: 2
|
||||
padding: 2
|
||||
@@ -50,6 +73,19 @@ SpriteAtlasAsset:
|
||||
- {fileID: 21300000, guid: d623a2b7e069a4c4592d3da48f476189, type: 3}
|
||||
- {fileID: 21300000, guid: 57e4117f4cd6ae54284898652e70d553, type: 3}
|
||||
bindAsDefault: 1
|
||||
isAtlasV2: 1
|
||||
isAtlasV2: 0
|
||||
cachedData: {fileID: 0}
|
||||
m_MasterAtlas: {fileID: 0}
|
||||
m_PackedSprites:
|
||||
- {fileID: 21300000, guid: 2761fc23b4aa7e34187ac5ffbc3fad9b, type: 3}
|
||||
- {fileID: 21300000, guid: f9a06e163014f4f46b14f4499d3e7240, type: 3}
|
||||
- {fileID: 21300000, guid: d623a2b7e069a4c4592d3da48f476189, type: 3}
|
||||
- {fileID: 21300000, guid: 57e4117f4cd6ae54284898652e70d553, type: 3}
|
||||
m_PackedSpriteNamesToIndex:
|
||||
- red_button
|
||||
- blue_button
|
||||
- white_background
|
||||
- white_button
|
||||
m_RenderDataMap: {}
|
||||
m_Tag: UIRaw_Atlas_Common
|
||||
m_IsVariant: 0
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c91b064c2cd7a34448ae0d6d7ee58e7f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 4343727234628468602
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9eaf6bdacd0683468b1dd697e3d2bce
|
||||
SpriteAtlasImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9bbd48a4abc45c46a92b92d0df3ae07
|
||||
guid: 3b549395c8849674b9cafbbf4c694e57
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a824de3af698c34bb4343dbb911498b
|
||||
guid: 4c9eb26aee01e8643bd4e6dc965d3366
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
40
UnityProject/Assets/Editor/I2Localization/I2Languages.asset
Normal file
@@ -0,0 +1,40 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2f0b0c553be8edd4682e9180fdd13e37, type: 3}
|
||||
m_Name: I2Languages
|
||||
m_EditorClassIdentifier:
|
||||
mSource:
|
||||
UserAgreesToHaveItOnTheScene: 0
|
||||
UserAgreesToHaveItInsideThePluginsFolder: 0
|
||||
GoogleLiveSyncIsUptoDate: 1
|
||||
mTerms: []
|
||||
CaseInsensitiveTerms: 0
|
||||
OnMissingTranslation: 1
|
||||
mTerm_AppName:
|
||||
mLanguages: []
|
||||
IgnoreDeviceLanguage: 0
|
||||
_AllowUnloadingLanguages: 0
|
||||
Google_WebServiceURL:
|
||||
Google_SpreadsheetKey:
|
||||
Google_SpreadsheetName:
|
||||
Google_LastUpdatedVersion:
|
||||
Google_Password: change_this
|
||||
GoogleUpdateFrequency: 3
|
||||
GoogleInEditorCheckFrequency: 2
|
||||
GoogleUpdateSynchronization: 1
|
||||
GoogleUpdateDelay: 0
|
||||
Assets: []
|
||||
Spreadsheet_LocalFileName:
|
||||
Spreadsheet_LocalCSVSeparator: ','
|
||||
Spreadsheet_LocalCSVEncoding: utf-8
|
||||
Spreadsheet_SpecializationAsRows: 1
|
||||
Spreadsheet_SortRows: 1
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a363de58f5d6e9e438b2b9a692187f6e
|
||||
guid: f069f2f03dfa55843a74dedc551eefb2
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
@@ -1,40 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于检测耗时。
|
||||
/// </summary>
|
||||
public class GameTickWatcher
|
||||
{
|
||||
private long _startTick;
|
||||
|
||||
public GameTickWatcher()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
_startTick = System.DateTime.Now.Ticks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用时。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float ElapseTime()
|
||||
{
|
||||
long endTick = System.DateTime.Now.Ticks;
|
||||
return (float)((endTick - _startTick) / 10000) / 1000.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出用时。
|
||||
/// </summary>
|
||||
public void LogUsedTime()
|
||||
{
|
||||
Log.Info($"Used Time: {this.ElapseTime()}");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7320165f7aa147a998a30fe2f7a5a5c2
|
||||
timeCreated: 1681989139
|
@@ -1,14 +1,14 @@
|
||||
using TEngine;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GameBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用单例。
|
||||
/// 全局对象必须继承于此。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">泛型T。</typeparam>
|
||||
public class Singleton<T> where T : new()
|
||||
/// <typeparam name="T">子类类型。</typeparam>
|
||||
public abstract class Singleton<T> : ISingleton where T : Singleton<T>, new()
|
||||
{
|
||||
private static T _instance;
|
||||
protected static T _instance = default(T);
|
||||
|
||||
public static T Instance
|
||||
{
|
||||
@@ -17,11 +17,43 @@ namespace GameBase
|
||||
if (null == _instance)
|
||||
{
|
||||
_instance = new T();
|
||||
Log.Assert(_instance != null);
|
||||
_instance.Init();
|
||||
SingletonSystem.Retain(_instance);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsValid => _instance != null;
|
||||
|
||||
protected Singleton()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
string st = new StackTrace().ToString();
|
||||
// using const string to compare simply
|
||||
if (!st.Contains("GameBase.Singleton`1[T].get_Instance"))
|
||||
{
|
||||
UnityEngine.Debug.LogError($"请必须通过Instance方法来实例化{typeof(T).FullName}类");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Active()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Release()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
SingletonSystem.Release(_instance);
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局MonoBehavior必须继承于此
|
||||
/// </summary>
|
||||
/// <typeparam name="T">子类类型</typeparam>
|
||||
public class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (CheckInstance())
|
||||
{
|
||||
OnLoad();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckInstance()
|
||||
{
|
||||
if (this == Instance)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Object.Destroy(gameObject);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void OnLoad()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (this == _instance)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断对象是否有效
|
||||
/// </summary>
|
||||
public static bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return _instance != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static T Active()
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static void Release()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
SingletonSystem.Release(_instance.gameObject);
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例
|
||||
/// </summary>
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
System.Type thisType = typeof(T);
|
||||
string instName = thisType.Name;
|
||||
GameObject go = SingletonSystem.GetGameObject(instName);
|
||||
if (go == null)
|
||||
{
|
||||
go = GameObject.Find($"/{instName}");
|
||||
if (go == null)
|
||||
{
|
||||
go = new GameObject(instName);
|
||||
go.transform.position = Vector3.zero;
|
||||
}
|
||||
SingletonSystem.Retain(go);
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
_instance = go.GetComponent<T>();
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = go.AddComponent<T>();
|
||||
}
|
||||
}
|
||||
|
||||
if (_instance == null)
|
||||
{
|
||||
Log.Error($"Can't create SingletonBehaviour<{typeof(T)}>");
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc365e281d234e61891bf9f922a0897a
|
||||
timeCreated: 1715574965
|
@@ -0,0 +1,141 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace GameBase
|
||||
{
|
||||
public interface ISingleton
|
||||
{
|
||||
/// <summary>
|
||||
/// 激活接口,通常用于在某个时机手动实例化
|
||||
/// </summary>
|
||||
void Active();
|
||||
|
||||
/// <summary>
|
||||
/// 释放接口
|
||||
/// </summary>
|
||||
void Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 框架中的全局对象与Unity场景依赖相关的DontDestroyOnLoad需要统一管理,方便重启游戏时清除工作
|
||||
/// </summary>
|
||||
public static class SingletonSystem
|
||||
{
|
||||
private static List<ISingleton> _singletons;
|
||||
private static Dictionary<string, GameObject> _gameObjects;
|
||||
|
||||
public static void Retain(ISingleton go)
|
||||
{
|
||||
if (_singletons == null)
|
||||
{
|
||||
_singletons = new List<ISingleton>();
|
||||
}
|
||||
|
||||
_singletons.Add(go);
|
||||
}
|
||||
|
||||
public static void Retain(GameObject go)
|
||||
{
|
||||
if (_gameObjects == null)
|
||||
{
|
||||
_gameObjects = new Dictionary<string, GameObject>();
|
||||
}
|
||||
|
||||
if (_gameObjects.TryAdd(go.name, go))
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Object.DontDestroyOnLoad(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Release(GameObject go)
|
||||
{
|
||||
if (_gameObjects != null && _gameObjects.ContainsKey(go.name))
|
||||
{
|
||||
_gameObjects.Remove(go.name);
|
||||
Object.Destroy(go);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Release(ISingleton go)
|
||||
{
|
||||
if (_singletons != null && _singletons.Contains(go))
|
||||
{
|
||||
_singletons.Remove(go);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Release()
|
||||
{
|
||||
if (_gameObjects != null)
|
||||
{
|
||||
foreach (var item in _gameObjects)
|
||||
{
|
||||
Object.Destroy(item.Value);
|
||||
}
|
||||
|
||||
_gameObjects.Clear();
|
||||
}
|
||||
|
||||
if (_singletons != null)
|
||||
{
|
||||
for (int i = _singletons.Count -1; i >= 0; i--)
|
||||
{
|
||||
_singletons[i].Release();
|
||||
}
|
||||
|
||||
_singletons.Clear();
|
||||
}
|
||||
|
||||
Resources.UnloadUnusedAssets();
|
||||
}
|
||||
|
||||
public static GameObject GetGameObject(string name)
|
||||
{
|
||||
GameObject go = null;
|
||||
if (_gameObjects != null)
|
||||
{
|
||||
_gameObjects.TryGetValue(name, out go);
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static bool ContainsKey(string name)
|
||||
{
|
||||
if (_gameObjects != null)
|
||||
{
|
||||
return _gameObjects.ContainsKey(name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Restart()
|
||||
{
|
||||
if (Camera.main != null)
|
||||
{
|
||||
Camera.main.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
Release();
|
||||
SceneManager.LoadScene(0);
|
||||
}
|
||||
|
||||
internal static ISingleton GetSingleton(string name)
|
||||
{
|
||||
for (int i = 0; i < _singletons.Count; ++i)
|
||||
{
|
||||
if (_singletons[i].ToString() == name)
|
||||
{
|
||||
return _singletons[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ad00b596d0743a4b04591fe52087d0f
|
||||
timeCreated: 1715574577
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40a878a415f34e7a855fc4916bbb8e6b
|
||||
timeCreated: 1702479104
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dcaa491f139438dbd963d8bbf0dba85
|
||||
timeCreated: 1702385397
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class BaseAttribute: Attribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 819c4eaddddd4646a100da2e3f19c3c7
|
||||
timeCreated: 1702385397
|
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class CodeTypes
|
||||
{
|
||||
private static CodeTypes _instance;
|
||||
public static CodeTypes Instance => _instance ??= new CodeTypes();
|
||||
|
||||
private readonly Dictionary<string, Type> _allTypes = new();
|
||||
private readonly UnOrderMultiMapSet<Type, Type> _types = new();
|
||||
|
||||
public void Init(Assembly[] assemblies)
|
||||
{
|
||||
Dictionary<string, Type> addTypes = GetAssemblyTypes(assemblies);
|
||||
foreach ((string fullName, Type type) in addTypes)
|
||||
{
|
||||
_allTypes[fullName] = type;
|
||||
|
||||
if (type.IsAbstract)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 记录所有的有BaseAttribute标记的的类型
|
||||
object[] objects = type.GetCustomAttributes(typeof(BaseAttribute), true);
|
||||
|
||||
foreach (object o in objects)
|
||||
{
|
||||
_types.Add(o.GetType(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<Type> GetTypes(Type systemAttributeType)
|
||||
{
|
||||
if (!_types.ContainsKey(systemAttributeType))
|
||||
{
|
||||
return new HashSet<Type>();
|
||||
}
|
||||
|
||||
return _types[systemAttributeType];
|
||||
}
|
||||
|
||||
public Dictionary<string, Type> GetTypes()
|
||||
{
|
||||
return _allTypes;
|
||||
}
|
||||
|
||||
public Type GetType(string typeName)
|
||||
{
|
||||
return _allTypes[typeName];
|
||||
}
|
||||
|
||||
public static Dictionary<string, Type> GetAssemblyTypes(params Assembly[] args)
|
||||
{
|
||||
Dictionary<string, Type> types = new Dictionary<string, Type>();
|
||||
|
||||
foreach (Assembly ass in args)
|
||||
{
|
||||
foreach (Type type in ass.GetTypes())
|
||||
{
|
||||
if (type.FullName != null)
|
||||
{
|
||||
types[type.FullName] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01fdfc4515314c579523ac3716005210
|
||||
timeCreated: 1702385429
|
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UnOrderMultiMapSet<TKey, TValue>: Dictionary<TKey, HashSet<TValue>>
|
||||
{
|
||||
public new HashSet<TValue> this[TKey t]
|
||||
{
|
||||
get
|
||||
{
|
||||
HashSet<TValue> set;
|
||||
if (!TryGetValue(t, out set))
|
||||
{
|
||||
set = new HashSet<TValue>();
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<TKey, HashSet<TValue>> GetDictionary()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Add(TKey t, TValue k)
|
||||
{
|
||||
HashSet<TValue> set;
|
||||
TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
set = new HashSet<TValue>();
|
||||
base[t] = set;
|
||||
}
|
||||
set.Add(k);
|
||||
}
|
||||
|
||||
public bool Remove(TKey t, TValue k)
|
||||
{
|
||||
HashSet<TValue> set;
|
||||
TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!set.Remove(k))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (set.Count == 0)
|
||||
{
|
||||
Remove(t);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Contains(TKey t, TValue k)
|
||||
{
|
||||
HashSet<TValue> set;
|
||||
TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return set.Contains(k);
|
||||
}
|
||||
|
||||
public new int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
foreach (KeyValuePair<TKey,HashSet<TValue>> kv in this)
|
||||
{
|
||||
count += kv.Value.Count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b798f0c1317c4caf9ace168f07b51d4f
|
||||
timeCreated: 1702385485
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dd993a020654e8bbcc4e70ea0029447
|
||||
timeCreated: 1695289810
|
@@ -1,189 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 红点个体行为。
|
||||
/// </summary>
|
||||
public class RedNoteBehaviour : UIWidget
|
||||
{
|
||||
public Action<bool> HaveRedNoteAction;
|
||||
|
||||
//当前红点类型
|
||||
public RedNoteNotify RedNoteNotifyType { get; private set; }
|
||||
|
||||
//启用时当作标记,解决带有ID,创建多个类似条目的情况
|
||||
public readonly List<ulong> IdParamList = new List<ulong>();
|
||||
private readonly List<ulong> _tmpIdParam = new List<ulong>();
|
||||
|
||||
private Image _image;
|
||||
|
||||
private Image Image
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_image == null && gameObject != null)
|
||||
{
|
||||
_image = gameObject.GetComponent<Image>();
|
||||
}
|
||||
return _image;
|
||||
}
|
||||
}
|
||||
|
||||
private Text _text;
|
||||
private Text Text
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_text == null && gameObject != null)
|
||||
{
|
||||
_text = FindChildComponent<Text>(rectTransform, "Text");
|
||||
}
|
||||
return _text;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _state = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前红点状态。
|
||||
/// </summary>
|
||||
public bool CurState
|
||||
{
|
||||
private set
|
||||
{
|
||||
_state = value;
|
||||
|
||||
if (Image == null)
|
||||
{
|
||||
gameObject.SetActive(_state);
|
||||
return;
|
||||
}
|
||||
|
||||
Color c = Image.color;
|
||||
c.a = _state ? 1f : 0.01f;
|
||||
Image.color = c;
|
||||
|
||||
if (HaveRedNoteAction != null)
|
||||
{
|
||||
HaveRedNoteAction(_state);
|
||||
}
|
||||
}
|
||||
get => _state;
|
||||
}
|
||||
|
||||
|
||||
//设置显示状态
|
||||
public void SetRedNoteState(bool state)
|
||||
{
|
||||
CurState = state;
|
||||
}
|
||||
|
||||
// 设置红点类型
|
||||
public void SetNotifyType(RedNoteNotify notifyType)
|
||||
{
|
||||
_tmpIdParam.Clear();
|
||||
SetNotifyType(notifyType, _tmpIdParam);
|
||||
}
|
||||
|
||||
#region 参数重载
|
||||
public void SetNotifyType(RedNoteNotify notifyType, ulong param1)
|
||||
{
|
||||
_tmpIdParam.Clear();
|
||||
_tmpIdParam.Add(param1);
|
||||
SetNotifyType(notifyType, _tmpIdParam);
|
||||
}
|
||||
|
||||
public void SetNotifyType(RedNoteNotify notifyType, ulong param1, ulong param2)
|
||||
{
|
||||
_tmpIdParam.Clear();
|
||||
_tmpIdParam.Add(param1);
|
||||
_tmpIdParam.Add(param2);
|
||||
SetNotifyType(notifyType, _tmpIdParam);
|
||||
}
|
||||
|
||||
public void SetNotifyType(RedNoteNotify notifyType, ulong param1, ulong param2, ulong param3)
|
||||
{
|
||||
_tmpIdParam.Clear();
|
||||
_tmpIdParam.Add(param1);
|
||||
_tmpIdParam.Add(param2);
|
||||
_tmpIdParam.Add(param3);
|
||||
SetNotifyType(notifyType, _tmpIdParam);
|
||||
}
|
||||
|
||||
public void SetNotifyType(RedNoteNotify notifyType, params ulong[] param)
|
||||
{
|
||||
_tmpIdParam.Clear();
|
||||
for (int i = 0; i < param.Length; i++)
|
||||
{
|
||||
_tmpIdParam.Add(param[i]);
|
||||
}
|
||||
SetNotifyType(notifyType, _tmpIdParam);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void SetNotifyType(RedNoteNotify notifyType, List<ulong> paramList)
|
||||
{
|
||||
RemoveNotifyBind();
|
||||
if (notifyType == RedNoteNotify.None) return;
|
||||
|
||||
IdParamList.Clear();
|
||||
IdParamList.AddRange(paramList);
|
||||
SetRedNoteNotifyProcess(notifyType);
|
||||
}
|
||||
|
||||
private void SetRedNoteNotifyProcess(RedNoteNotify notifyType)
|
||||
{
|
||||
// 移除红点通知的绑定
|
||||
if (Image != null)
|
||||
{
|
||||
Image.rectTransform.SetAsLastSibling();
|
||||
}
|
||||
|
||||
RedNoteNotifyType = notifyType;
|
||||
|
||||
RedNoteMgr.Instance.RegisterNotify(RedNoteNotifyType, this);
|
||||
|
||||
if (!RedNoteMgr.Instance.IsNumType(notifyType, IdParamList))
|
||||
{
|
||||
CurState = RedNoteMgr.Instance.GetNotifyValue(RedNoteNotifyType, IdParamList);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRedNotePointNum(RedNoteMgr.Instance.GetNotifyPointNum(RedNoteNotifyType, IdParamList));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除红点通知的绑定。
|
||||
/// </summary>
|
||||
public void RemoveNotifyBind()
|
||||
{
|
||||
if (RedNoteNotifyType != RedNoteNotify.None)
|
||||
{
|
||||
RedNoteMgr.Instance.UnRegisterNotify(RedNoteNotifyType, this);
|
||||
}
|
||||
|
||||
CurState = false;
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
RemoveNotifyBind();
|
||||
}
|
||||
|
||||
public void SetRedNotePointNum(int pointNum)
|
||||
{
|
||||
if (Text != null)
|
||||
{
|
||||
Text.text = pointNum > 0 ? pointNum.ToString() : string.Empty;
|
||||
|
||||
CurState = pointNum > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dba30ea267ff4b988310dec14c0df1c3
|
||||
timeCreated: 1687263893
|
@@ -1,85 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary> 红点关联 </summary>
|
||||
public class RedNoteCheckMgr
|
||||
{
|
||||
public string m_ownerStr;
|
||||
public List<string> m_childList { get; private set; }
|
||||
|
||||
public RedNoteCheckMgr(RedNoteNotify ower, List<RedNoteNotify> childList)
|
||||
{
|
||||
m_ownerStr = ower.ToString();
|
||||
m_childList = new List<string>();
|
||||
for (int i = 0; i < childList.Count; i++)
|
||||
{
|
||||
var value = childList[i];
|
||||
m_childList.Add(value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public RedNoteCheckMgr(string paramKey)
|
||||
{
|
||||
m_ownerStr = paramKey;
|
||||
}
|
||||
|
||||
public bool AddChild(string childKey)
|
||||
{
|
||||
if (m_childList == null)
|
||||
{
|
||||
m_childList = new List<string>();
|
||||
}
|
||||
if (!m_childList.Contains(childKey))
|
||||
{
|
||||
m_childList.Add(childKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CheckChildRedNote()
|
||||
{
|
||||
var valueItem = RedNoteMgr.Instance.GetNotifyValueItem(m_ownerStr);
|
||||
|
||||
bool childHaveRed = false;
|
||||
int childNotePointNum = 0;
|
||||
|
||||
int count = m_childList.Count;
|
||||
for (var index = 0; index < count; index++)
|
||||
{
|
||||
var child = m_childList[index];
|
||||
var childItem = RedNoteMgr.Instance.GetNotifyValueItem(child);
|
||||
if (childItem.GetRedNoteType() == RedNoteType.Simple)
|
||||
{
|
||||
if (RedNoteMgr.Instance.GetNotifyValue(child))
|
||||
{
|
||||
childHaveRed = true;
|
||||
childNotePointNum++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
childNotePointNum += childItem.GetRedNotePointNum();
|
||||
}
|
||||
}
|
||||
|
||||
if (valueItem.GetRedNoteType() == RedNoteType.Simple)
|
||||
{
|
||||
RedNoteMgr.Instance.SetNotifyKeyValue(m_ownerStr, childHaveRed);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedNoteMgr.Instance.SetNotifyKeyPointNum(m_ownerStr, childNotePointNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool CheckChild(string childKey)
|
||||
{
|
||||
bool red = RedNoteMgr.Instance.GetNotifyValue(childKey);
|
||||
return red;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dd181174bbf408e9932a6f9484e41a5
|
||||
timeCreated: 1687263893
|
@@ -1,669 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GameBase;
|
||||
using GameLogic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
#region 红点添加步骤
|
||||
|
||||
/// 1,增加RedNoteNotify定义,加入新的红点枚举。
|
||||
/// 2,添加红点关联,关联定义在InitRelation,查看当前有的关联关系,确定是增加还是重新创建
|
||||
/// 3,把RedNoteBehaviour挂在红点图片上,红点图片一般放置在需要显示红点的按钮/页签上,设置脚本上的枚举类型
|
||||
/// 4,如果是带参数的红点类型,在红点所在的UI声明红点对象,对参数进行设置,参数统一为uint,一般用一个可以唯一区分的ID。
|
||||
/// 有多个参数时,每后一个参数节点都是前一个参数的子节点。 无参数为该层级的根节点。
|
||||
/// 5,红点激活/隐藏
|
||||
/// 在对应模块数据管理类中,检测达到红点激活条件,或红点消失条件,调用SetNotifyValue激活/隐藏红点
|
||||
#endregion
|
||||
|
||||
public enum RedNoteNotify
|
||||
{
|
||||
None = 0,
|
||||
CharacterMain,
|
||||
ShopMain,
|
||||
BagMain,
|
||||
BagUseType,
|
||||
ExploreMain,
|
||||
HomeUI,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红点指引
|
||||
/// </summary>
|
||||
public class RedNoteMgr : Singleton<RedNoteMgr>
|
||||
{
|
||||
//红点状态记录
|
||||
private Dictionary<string, RedNoteValueItem> _notifyMap;
|
||||
|
||||
//红点关联
|
||||
private readonly Dictionary<string, RedNoteCheckMgr> _checkDic = new Dictionary<string, RedNoteCheckMgr>();
|
||||
|
||||
/// <summary>
|
||||
/// child to parent list
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, List<string>> _checkOwnDic = new Dictionary<string, List<string>>();
|
||||
|
||||
private readonly Dictionary<string, RedNoteKeyStruct> _keyConvertDic = new Dictionary<string, RedNoteKeyStruct>();
|
||||
private readonly Dictionary<string, RedNoteStructDic> _keyDic = new Dictionary<string, RedNoteStructDic>();
|
||||
|
||||
/// <summary>
|
||||
/// 红点映射
|
||||
/// key => 红点名称
|
||||
/// val => 对应的红点类型
|
||||
/// </summary>
|
||||
private Dictionary<string, RedNoteNotify> _dicRedNoteMap;
|
||||
|
||||
private Dictionary<int, string> _notifyStringMap;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
InitState();
|
||||
InitRedNoteConfig();
|
||||
InitRelation();
|
||||
InitRedNoteTween();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局缓动缩放
|
||||
/// </summary>
|
||||
public Vector3 GlobalTwScale { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化红点缓动
|
||||
/// </summary>
|
||||
private void InitRedNoteTween()
|
||||
{
|
||||
// LeanTween.value(LeanTween.tweenEmpty, OnRedNoteTween, 1f, 0.75f, 0.5f).setLoopPingPong();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓动
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
private void OnRedNoteTween(float value)
|
||||
{
|
||||
GlobalTwScale = value * Vector3.one;
|
||||
}
|
||||
|
||||
//注册红点通知
|
||||
public void RegisterNotify(RedNoteNotify notify, RedNoteBehaviour redNote)
|
||||
{
|
||||
RedNoteValueItem redNoteValueItem = GetOrNewNotifyValueItem(notify, redNote.IdParamList);
|
||||
redNoteValueItem.AddRedNote(redNote);
|
||||
}
|
||||
|
||||
//销毁红点通知
|
||||
public void UnRegisterNotify(RedNoteNotify notify, RedNoteBehaviour redNote)
|
||||
{
|
||||
RedNoteValueItem redNoteValueItem = GetOrNewNotifyValueItem(notify, redNote.IdParamList);
|
||||
if (redNoteValueItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
redNoteValueItem.RemoveRedNote(redNote);
|
||||
}
|
||||
|
||||
private readonly List<ulong> _tmpRedNoteParams = new List<ulong>();
|
||||
|
||||
/// <summary>
|
||||
/// 设置红点状态。
|
||||
/// </summary>
|
||||
/// <param name="notify"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetNotifyValue(RedNoteNotify notify, bool value)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
SetNotifyValue(notify, value, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
#region 参数重载 bool
|
||||
|
||||
public void SetNotifyValue(RedNoteNotify notify, bool value, ulong param1)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
_tmpRedNoteParams.Add(param1);
|
||||
SetNotifyValue(notify, value, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
public void SetNotifyValue(RedNoteNotify notify, bool value, ulong param1, ulong param2)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
_tmpRedNoteParams.Add(param1);
|
||||
_tmpRedNoteParams.Add(param2);
|
||||
SetNotifyValue(notify, value, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
public void SetNotifyValue(RedNoteNotify notify, bool value, params ulong[] param)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
for (var i = 0; i < param.Length; i++)
|
||||
{
|
||||
_tmpRedNoteParams.Add(param[i]);
|
||||
}
|
||||
|
||||
SetNotifyValue(notify, value, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetNotifyValue(RedNoteNotify notify, bool value, List<ulong> redNoteParamList)
|
||||
{
|
||||
var key = BuildKey(notify, redNoteParamList);
|
||||
if (!value && !_notifyMap.TryGetValue(key, out var redNoteValueItem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetOrNewNotifyValueItem(notify, redNoteParamList);
|
||||
MarkNotifyKeyValueDirty(key, value);
|
||||
}
|
||||
|
||||
public void MarkNotifyKeyValueDirty(string key, bool value)
|
||||
{
|
||||
if (!_notifyMap.TryGetValue(key, out var redNoteValueItem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
redNoteValueItem.SetStateDirty(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置红点状态。
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetNotifyKeyValue(string key, bool value)
|
||||
{
|
||||
if (!_notifyMap.TryGetValue(key, out var redNoteValueItem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//设置红点状态
|
||||
if (redNoteValueItem.SetRedNoteState(value))
|
||||
{
|
||||
//设置红点关联状态
|
||||
CalcRedNoteRelation(key);
|
||||
}
|
||||
}
|
||||
|
||||
//设置红点状态数量
|
||||
public void SetNotifyKeyPointNum(string key, int pointNum)
|
||||
{
|
||||
if (!_notifyMap.TryGetValue(key, out var redNoteValueItem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (redNoteValueItem.SetRedNotePoint(pointNum))
|
||||
{
|
||||
//设置红点关联状态
|
||||
CalcRedNoteRelation(key);
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetNotifyValue(RedNoteNotify notify, ulong param1)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
_tmpRedNoteParams.Add(param1);
|
||||
return GetNotifyValue(notify, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
public bool GetNotifyValue(RedNoteNotify notify, ulong param1, ulong param2)
|
||||
{
|
||||
_tmpRedNoteParams.Clear();
|
||||
_tmpRedNoteParams.Add(param1);
|
||||
_tmpRedNoteParams.Add(param2);
|
||||
return GetNotifyValue(notify, _tmpRedNoteParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红点状态。
|
||||
/// </summary>
|
||||
/// <param name="notify"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public bool GetNotifyValue(RedNoteNotify notify, List<ulong> param = null)
|
||||
{
|
||||
if (notify == (uint)RedNoteNotify.None)
|
||||
return false;
|
||||
|
||||
RedNoteValueItem item = GetOrNewNotifyValueItem(notify, param);
|
||||
return item.GetRedNoteState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红点数量。
|
||||
/// </summary>
|
||||
/// <param name="notify"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public int GetNotifyPointNum(RedNoteNotify notify, List<ulong> param)
|
||||
{
|
||||
if (notify == (uint)RedNoteNotify.None)
|
||||
return 0;
|
||||
|
||||
RedNoteValueItem item = GetOrNewNotifyValueItem(notify, param);
|
||||
return item.GetRedNotePointNum();
|
||||
}
|
||||
|
||||
public bool GetNotifyValue(string paramKey)
|
||||
{
|
||||
if (_notifyMap.TryGetValue(paramKey, out var redNoteValueItem))
|
||||
{
|
||||
return redNoteValueItem.GetRedNoteState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理红点状态.
|
||||
/// </summary>
|
||||
/// <param name="notify"></param>
|
||||
public void ClearNotifyValue(RedNoteNotify notify)
|
||||
{
|
||||
var notifyStr = NotifyTypeToString(notify);
|
||||
RecursiveClearNotifyKeyValue(notifyStr);
|
||||
|
||||
RedNoteValueItem redNoteValueItem = GetNotifyValueItem(notifyStr);
|
||||
redNoteValueItem.ClearRedNoteState(false);
|
||||
CalcRedNoteRelation(notifyStr);
|
||||
}
|
||||
|
||||
public void RecursiveClearNotifyKeyValue(string key)
|
||||
{
|
||||
if (!_checkDic.TryGetValue(key, out var checkMgr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var childList = checkMgr.m_childList;
|
||||
foreach (var childKey in childList)
|
||||
{
|
||||
RedNoteValueItem redNoteValueItem = GetNotifyValueItem(childKey);
|
||||
redNoteValueItem.ClearRedNoteState(false);
|
||||
|
||||
RecursiveClearNotifyKeyValue(childKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理数据。
|
||||
/// </summary>
|
||||
public void OnRoleLogout()
|
||||
{
|
||||
var enumerator = _notifyMap.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
enumerator.Current.Value.ClearRedNoteState(true);
|
||||
}
|
||||
|
||||
enumerator.Dispose();
|
||||
}
|
||||
|
||||
public string NotifyTypeToString(RedNoteNotify notify)
|
||||
{
|
||||
_notifyStringMap.TryGetValue((int)notify, out var str);
|
||||
return str;
|
||||
}
|
||||
|
||||
public string BuildKey(RedNoteNotify notifyType, List<ulong> paramList)
|
||||
{
|
||||
var notifyStr = NotifyTypeToString(notifyType);
|
||||
if (notifyStr == null)
|
||||
{
|
||||
Log.Error("RedNoteNotifyId :{0} Not Exit! Please Check", notifyType.ToString());
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (!_keyDic.TryGetValue(notifyStr, out var dicData))
|
||||
{
|
||||
dicData = new RedNoteStructDic();
|
||||
_keyDic[notifyStr] = dicData;
|
||||
}
|
||||
|
||||
var key = dicData.TryGetKey(notifyStr, paramList);
|
||||
return key;
|
||||
}
|
||||
|
||||
public static string GetKeyString(string notify, List<ulong> paramList)
|
||||
{
|
||||
if (paramList == null || paramList.Count == 0)
|
||||
{
|
||||
return notify;
|
||||
}
|
||||
|
||||
string key;
|
||||
if (paramList.Count <= 1)
|
||||
{
|
||||
key = $"{notify}-{paramList[0]}";
|
||||
}
|
||||
else if (paramList.Count <= 2)
|
||||
{
|
||||
key = $"{notify}-{paramList[0]}-{paramList[1]}";
|
||||
}
|
||||
else if (paramList.Count <= 3)
|
||||
{
|
||||
key = $"{notify}-{paramList[0]}-{paramList[1]}-{paramList[2]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.Append(notify + "-");
|
||||
for (var i = 0; i < paramList.Count; i++)
|
||||
{
|
||||
s.Append(paramList[i]);
|
||||
if (i != paramList.Count - 1)
|
||||
s.Append("-");
|
||||
}
|
||||
|
||||
key = s.ToString();
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public void SetKeyConvertDic(string key, RedNoteKeyStruct keyStruct)
|
||||
{
|
||||
_keyConvertDic[key] = keyStruct;
|
||||
}
|
||||
|
||||
private readonly List<ulong> _tmpParamList = new List<ulong>();
|
||||
|
||||
/// <summary>
|
||||
/// 计算红点关联.
|
||||
/// </summary>
|
||||
/// <param name="notifyKey"></param>
|
||||
private void CalcRedNoteRelation(string notifyKey)
|
||||
{
|
||||
var key = notifyKey;
|
||||
if (_checkOwnDic.TryGetValue(key, out var ownerList))
|
||||
{
|
||||
foreach (var owner in ownerList)
|
||||
{
|
||||
if (_checkDic.TryGetValue(owner, out var checker))
|
||||
{
|
||||
checker.CheckChildRedNote();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化红点状态.
|
||||
/// </summary>
|
||||
private void InitState()
|
||||
{
|
||||
var array = (RedNoteNotify[])Enum.GetValues(typeof(RedNoteNotify));
|
||||
|
||||
var redNoteCnt = array.Length;
|
||||
_notifyMap = new Dictionary<string, RedNoteValueItem>();
|
||||
_dicRedNoteMap = new Dictionary<string, RedNoteNotify>(redNoteCnt);
|
||||
_notifyStringMap = new Dictionary<int, string>(redNoteCnt);
|
||||
|
||||
foreach (var redNoteNotify in array)
|
||||
{
|
||||
var redNoteStr = redNoteNotify.ToString();
|
||||
_dicRedNoteMap.Add(redNoteStr, redNoteNotify);
|
||||
_notifyStringMap.Add((int)redNoteNotify, redNoteStr);
|
||||
|
||||
var key = BuildKey(redNoteNotify, _tmpParamList);
|
||||
var redNoteValueItem = new RedNoteValueItem();
|
||||
bool isNumType = IsNumType(redNoteNotify, null);
|
||||
redNoteValueItem.Init(key, isNumType ? RedNoteType.WithNum : RedNoteType.Simple);
|
||||
_notifyMap.Add(key, redNoteValueItem);
|
||||
}
|
||||
}
|
||||
|
||||
public RedNoteValueItem GetNotifyValueItem(string key)
|
||||
{
|
||||
_notifyMap.TryGetValue(key, out var redNoteValueItem);
|
||||
return redNoteValueItem;
|
||||
}
|
||||
|
||||
private RedNoteValueItem GetOrNewNotifyValueItem(RedNoteNotify notify, List<ulong> paramList)
|
||||
{
|
||||
var key = BuildKey(notify, paramList);
|
||||
var redNoteValueItem = GetNotifyValueItem(key);
|
||||
|
||||
if (redNoteValueItem == null)
|
||||
{
|
||||
List<ulong> tmpParamList = new List<ulong>(paramList);
|
||||
|
||||
//从后往前创建item,如(A, 1, 2)会创建A-1-2,A-1,A。
|
||||
string lastChildKey = string.Empty;
|
||||
int paramIndex = paramList.Count;
|
||||
while (paramIndex >= 0)
|
||||
{
|
||||
var keyStr = BuildKey(notify, tmpParamList);
|
||||
|
||||
if (!_notifyMap.ContainsKey(keyStr))
|
||||
{
|
||||
RedNoteValueItem noteValueItem = new RedNoteValueItem();
|
||||
bool isNumType = IsNumType(notify, paramList);
|
||||
noteValueItem.Init(keyStr, isNumType ? RedNoteType.WithNum : RedNoteType.Simple);
|
||||
_notifyMap.Add(keyStr, noteValueItem);
|
||||
}
|
||||
|
||||
//叶子节点跳过(因为他没有子节点)
|
||||
if (tmpParamList.Count < paramList.Count)
|
||||
{
|
||||
bool addedChild;
|
||||
if (!_checkDic.TryGetValue(keyStr, out var checkMgr))
|
||||
{
|
||||
checkMgr = new RedNoteCheckMgr(keyStr);
|
||||
addedChild = checkMgr.AddChild(lastChildKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
addedChild = checkMgr.AddChild(lastChildKey);
|
||||
}
|
||||
|
||||
if (addedChild)
|
||||
{
|
||||
AddDic(checkMgr); //重新生成父子关系
|
||||
}
|
||||
}
|
||||
|
||||
lastChildKey = keyStr;
|
||||
paramIndex--;
|
||||
if (paramIndex < tmpParamList.Count && tmpParamList.Count > 0)
|
||||
{
|
||||
tmpParamList.RemoveAt(paramIndex);
|
||||
}
|
||||
}
|
||||
|
||||
redNoteValueItem = _notifyMap[key];
|
||||
}
|
||||
|
||||
return redNoteValueItem;
|
||||
}
|
||||
|
||||
public void AddDic(RedNoteNotify owner, List<RedNoteNotify> childList)
|
||||
{
|
||||
AddDic(new RedNoteCheckMgr(owner, childList));
|
||||
}
|
||||
|
||||
private void AddDic(RedNoteCheckMgr checker)
|
||||
{
|
||||
var owner = checker.m_ownerStr;
|
||||
_checkDic[owner] = checker;
|
||||
|
||||
var childList = checker.m_childList;
|
||||
int count = childList.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var child = childList[i];
|
||||
if (!_checkOwnDic.TryGetValue(child, out var ownerList))
|
||||
{
|
||||
ownerList = new List<string>();
|
||||
_checkOwnDic[child] = ownerList;
|
||||
}
|
||||
|
||||
if (!ownerList.Contains(owner))
|
||||
{
|
||||
ownerList.Add(owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNumType(RedNoteNotify noteNotify, List<ulong> paramList)
|
||||
{
|
||||
if (paramList is { Count: > 0 })
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 通过名字获取红点类型
|
||||
public static RedNoteNotify GetRedNoteByName(string redNoteName)
|
||||
{
|
||||
Instance._dicRedNoteMap.TryGetValue(redNoteName, out var redNote);
|
||||
|
||||
return redNote;
|
||||
}
|
||||
|
||||
public void OnUpdate()
|
||||
{
|
||||
foreach (var redNoteValueItem in _notifyMap)
|
||||
{
|
||||
redNoteValueItem.Value.CheckDirty();
|
||||
}
|
||||
}
|
||||
|
||||
#region 初始化红点
|
||||
|
||||
/// <summary>
|
||||
/// 初始化红点配置表
|
||||
/// </summary>
|
||||
private void InitRedNoteConfig()
|
||||
{
|
||||
// ResDictionaryList<uint, RedNoteConfig> cfgs = new ResDictionaryList<uint, RedNoteConfig>();
|
||||
// cfgs.Init(val => val.RedNoteParentID);
|
||||
// List<RedNoteNotify> list = new List<RedNoteNotify>();
|
||||
// foreach (var kv in cfgs.Data)
|
||||
// {
|
||||
// list.Clear();
|
||||
// foreach (var cfg in kv.Value)
|
||||
// {
|
||||
// list.Add((RedNoteNotify)cfg.RedNoteID);
|
||||
// }
|
||||
//
|
||||
// AddDic((RedNoteNotify)kv.Key, list);
|
||||
// }
|
||||
}
|
||||
|
||||
//初始化红点关联
|
||||
private void InitRelation()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
public class RedNoteStructDic
|
||||
{
|
||||
private readonly List<RedNoteKeyStruct> _keyStructList = new List<RedNoteKeyStruct>();
|
||||
|
||||
public string TryGetKey(string notify, List<ulong> paramList)
|
||||
{
|
||||
string key = string.Empty;
|
||||
List<RedNoteKeyStruct> list = _keyStructList;
|
||||
{
|
||||
int count = list.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var keyStruct = list[i];
|
||||
if (keyStruct.IsSame(notify, paramList))
|
||||
{
|
||||
key = keyStruct.Key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
var keyStruct = new RedNoteKeyStruct(notify, paramList);
|
||||
key = keyStruct.Key;
|
||||
RedNoteMgr.Instance.SetKeyConvertDic(key, keyStruct);
|
||||
list.Add(keyStruct);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public class RedNoteKeyStruct
|
||||
{
|
||||
public string Notify;
|
||||
public List<ulong> ParamList;
|
||||
|
||||
public RedNoteKeyStruct(string notify, List<ulong> paramList)
|
||||
{
|
||||
Notify = notify;
|
||||
if (paramList != null)
|
||||
{
|
||||
ParamList = new List<ulong>(paramList);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParamList = new List<ulong>();
|
||||
}
|
||||
}
|
||||
|
||||
private string _key;
|
||||
|
||||
public string Key
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_key))
|
||||
{
|
||||
_key = RedNoteMgr.GetKeyString(Notify, ParamList);
|
||||
}
|
||||
return _key;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSame(string notify, List<ulong> paramList)
|
||||
{
|
||||
if (notify != Notify)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var list1 = paramList;
|
||||
var list2 = ParamList;
|
||||
|
||||
int cnt1 = list1?.Count ?? 0;
|
||||
int cnt2 = list2?.Count ?? 0;
|
||||
|
||||
if (cnt1 != cnt2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cnt1 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cnt1; i++)
|
||||
{
|
||||
// ReSharper disable PossibleNullReferenceException
|
||||
if (list1[i] != list2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66ededab0a1e409588f150be58193032
|
||||
timeCreated: 1687263893
|
@@ -1,159 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class RedNoteValueItem
|
||||
{
|
||||
public string m_key;
|
||||
//所有关联的红点UI
|
||||
private HashSet<RedNoteBehaviour> m_redNoteDic = new HashSet<RedNoteBehaviour>();
|
||||
private bool m_state;
|
||||
private int m_pointNum;
|
||||
private RedNoteType m_noteType;
|
||||
|
||||
private bool m_dirty;
|
||||
private bool m_tmpState;
|
||||
|
||||
public void Init(string keyStr, RedNoteType noteType)
|
||||
{
|
||||
m_key = keyStr;
|
||||
m_noteType = noteType;
|
||||
}
|
||||
|
||||
//添加红点对象
|
||||
public void AddRedNote(RedNoteBehaviour redNote)
|
||||
{
|
||||
m_redNoteDic.Add(redNote);
|
||||
}
|
||||
|
||||
//移除对象
|
||||
public void RemoveRedNote(RedNoteBehaviour redNote)
|
||||
{
|
||||
m_redNoteDic.Remove(redNote);
|
||||
}
|
||||
|
||||
//获取具体对象的状态
|
||||
public bool GetRedNoteState()
|
||||
{
|
||||
if (m_dirty)
|
||||
{
|
||||
return m_tmpState;
|
||||
}
|
||||
|
||||
return m_state;
|
||||
}
|
||||
|
||||
//获取具体对象的红点数
|
||||
public int GetRedNotePointNum()
|
||||
{
|
||||
return m_pointNum;
|
||||
}
|
||||
|
||||
public RedNoteType GetRedNoteType()
|
||||
{
|
||||
return m_noteType;
|
||||
}
|
||||
|
||||
public void SetStateDirty(bool state)
|
||||
{
|
||||
m_dirty = m_state != state;
|
||||
m_tmpState = state;
|
||||
}
|
||||
|
||||
//设置对象状态
|
||||
public bool SetRedNoteState(bool state)
|
||||
{
|
||||
bool chg = state != m_state;
|
||||
m_state = state;
|
||||
if (chg)
|
||||
{
|
||||
SetBehaviourState(state);
|
||||
}
|
||||
|
||||
return chg;
|
||||
}
|
||||
|
||||
public bool SetRedNotePoint(int num)
|
||||
{
|
||||
if (m_pointNum != num)
|
||||
{
|
||||
m_pointNum = num;
|
||||
SetBehaviourPoint(num);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetBehaviourState(bool state)
|
||||
{
|
||||
//检查是否注册过具体对象
|
||||
foreach (var redNote in m_redNoteDic)
|
||||
{
|
||||
if (redNote == null || redNote.gameObject == null)
|
||||
continue;
|
||||
|
||||
redNote.SetRedNoteState(state);
|
||||
}
|
||||
|
||||
// 移除空的红点
|
||||
ClearTheNullRedNote();
|
||||
}
|
||||
|
||||
private void SetBehaviourPoint(int pointNum)
|
||||
{
|
||||
foreach (var redNote in m_redNoteDic)
|
||||
{
|
||||
if (redNote == null || redNote.gameObject == null)
|
||||
continue;
|
||||
|
||||
redNote.SetRedNotePointNum(pointNum);
|
||||
}
|
||||
|
||||
// 移除空的红点
|
||||
ClearTheNullRedNote();
|
||||
}
|
||||
|
||||
// 移除空的红点
|
||||
private void ClearTheNullRedNote()
|
||||
{
|
||||
m_redNoteDic.RemoveWhere(redNote => redNote == null || redNote.gameObject == null);
|
||||
}
|
||||
|
||||
//清理状态
|
||||
public void ClearRedNoteState(bool clearBehavior)
|
||||
{
|
||||
foreach (var redNote in m_redNoteDic)
|
||||
{
|
||||
if (redNote != null)
|
||||
{
|
||||
redNote.SetRedNoteState(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (clearBehavior)
|
||||
{
|
||||
m_redNoteDic.Clear();
|
||||
}
|
||||
|
||||
m_state = false;
|
||||
m_dirty = false;
|
||||
m_tmpState = false;
|
||||
}
|
||||
|
||||
public void CheckDirty()
|
||||
{
|
||||
if (m_dirty)
|
||||
{
|
||||
m_dirty = false;
|
||||
RedNoteMgr.Instance.SetNotifyKeyValue(m_key, m_tmpState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum RedNoteType
|
||||
{
|
||||
Simple,
|
||||
WithNum,
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c29f4a552c34bd8ab9d2c64b5b2b49d
|
||||
timeCreated: 1687263893
|
@@ -1,58 +0,0 @@
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class RedNoteWidget : UIWidget
|
||||
{
|
||||
#region 脚本工具生成的代码
|
||||
public override void ScriptGenerator()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
private Image m_image;
|
||||
public RedNoteBehaviour m_redNote;
|
||||
public override void OnCreate()
|
||||
{
|
||||
m_redNote = CreateWidget<RedNoteBehaviour>(gameObject);
|
||||
m_image = gameObject.GetComponent<Image>();
|
||||
rectTransform.anchoredPosition = Vector2.zero;
|
||||
SetNotifyState(false);
|
||||
}
|
||||
|
||||
public void SetNotifyType(RedNoteNotify notifyType)
|
||||
{
|
||||
m_redNote.SetNotifyType(notifyType);
|
||||
}
|
||||
public void SetNotifyType(RedNoteNotify notifyType, ulong param1)
|
||||
{
|
||||
m_redNote.SetNotifyType(notifyType, param1);
|
||||
}
|
||||
public void SetNotifyType(RedNoteNotify notifyType, ulong param1, ulong param2)
|
||||
{
|
||||
m_redNote.SetNotifyType(notifyType, param1, param2);
|
||||
}
|
||||
|
||||
public void SetNotifyState(bool state)
|
||||
{
|
||||
m_redNote.SetRedNoteState(state);
|
||||
}
|
||||
|
||||
public void SetSprite(string sprite)
|
||||
{
|
||||
m_image.sprite = LoadAsset<Sprite>(sprite);
|
||||
m_image.SetNativeSize();
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
/*if (!m_redNote.CurState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
gameObject.transform.localScale = RedNoteMgr.Instance.GlobalTwScale;*/
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2644c5700a07442a995008ee9fa8159d
|
||||
timeCreated: 1695289825
|