Compare commits
115 Commits
TEngine4.0
...
TEngine5.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
aad8ff3ee5 | ||
![]() |
df25a1adad | ||
![]() |
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 |
@@ -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 // 热更主入口注册系统
|
||||
```
|
@@ -51,17 +51,15 @@ public abstract class Module : 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 真机运行
|
||||
|
||||

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

|
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/WebGL-RunSuccessed.png
Normal file
After Width: | Height: | Size: 101 KiB |
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
|
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}"
|
@@ -42,16 +42,9 @@ public class ConfigSystem : Singleton<ConfigSystem>
|
||||
/// <returns>ByteBuf</returns>
|
||||
private ByteBuf LoadByteBuf(string file)
|
||||
{
|
||||
TextAsset textAsset = null;
|
||||
textAsset = GameModule.Resource.GetPreLoadAsset<TextAsset>(file);
|
||||
if (textAsset != null)
|
||||
{
|
||||
return new ByteBuf(textAsset.bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
textAsset = GameModule.Resource.LoadAsset<TextAsset>(file);
|
||||
return new ByteBuf(textAsset.bytes);
|
||||
}
|
||||
TextAsset textAsset = GameModule.Resource.LoadAsset<TextAsset>(file);
|
||||
byte[] bytes = textAsset.bytes;
|
||||
GameModule.Resource.UnloadAsset(textAsset);
|
||||
return new ByteBuf(bytes);
|
||||
}
|
||||
}
|
@@ -1,3 +1,6 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../..
|
||||
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
|
||||
set CONF_ROOT=.
|
||||
|
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
|
@@ -1,3 +1,6 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../..
|
||||
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
|
||||
set CONF_ROOT=.
|
||||
|
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
|
@@ -1,3 +1,6 @@
|
||||
Cd /d %~dp0
|
||||
echo %CD%
|
||||
|
||||
set WORKSPACE=../../
|
||||
set LUBAN_DLL=%WORKSPACE%/Tools/Luban/Luban.dll
|
||||
set CONF_ROOT=.
|
||||
|
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
|
45
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): 简单介绍。
|
||||
@@ -53,39 +50,38 @@
|
||||
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
|
||||
@@ -94,7 +90,7 @@ TEngine
|
||||
```
|
||||
|
||||
- 必要:项目使用了以下第三方插件,请自行购买导入:
|
||||
- /Unity/Assets/Plugins/Sirenix
|
||||
- /UnityProject/Assets/Plugins/Sirenix
|
||||
|
||||
---
|
||||
## <strong>优质开源项目推荐
|
||||
@@ -105,12 +101,11 @@ TEngine
|
||||
|
||||
#### <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 coffee.
|
||||
## <strong>Buy me a 奶茶.
|
||||
|
||||
[您的赞助会让我们做得更快更好,如果觉得TEngine对您有帮助,不妨赞助我买杯咖啡吧~](Books/Donate.md)
|
||||
[您的赞助会让我们做得更快更好,如果觉得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
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
|
@@ -1,8 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b763f43bfb633944aa8955535b965c1f
|
||||
guid: c91b064c2cd7a34448ae0d6d7ee58e7f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
mainObjectFileID: 4343727234628468602
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9eaf6bdacd0683468b1dd697e3d2bce
|
||||
SpriteAtlasImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,16 +0,0 @@
|
||||
[
|
||||
{
|
||||
"ResPath": "Assets/AssetRaw/Effects",
|
||||
"CacheTime": 300,
|
||||
"MaxPoolCnt": 30,
|
||||
"PoolGoFreeTime": 300,
|
||||
"MinPoolCnt": 0
|
||||
},
|
||||
{
|
||||
"ResPath": "Assets/AssetRaw/PoolObjects/",
|
||||
"CacheTime": 300,
|
||||
"MaxPoolCnt": 30,
|
||||
"PoolGoFreeTime": 300,
|
||||
"MinPoolCnt": 0
|
||||
}
|
||||
]
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0e67891bd0f0c7449b345c622ed6b0e
|
||||
guid: 3b549395c8849674b9cafbbf4c694e57
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7f738dc5a266e94d9e9870fc76009c2
|
||||
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
|
@@ -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,57 +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.SetSprite(sprite);
|
||||
}
|
||||
|
||||
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
|
@@ -1,49 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 封装一个角色可能用到的各种shader场景。
|
||||
/// </summary>
|
||||
class ActorShaderGroup
|
||||
{
|
||||
private readonly TShader[] _allShader = new TShader[(int)ActorShaderEnvType.EnvTypeMax];
|
||||
|
||||
/// <summary>
|
||||
/// 增加Shader到角色Shader分组。
|
||||
/// </summary>
|
||||
/// <param name="shaderType">当前环境类型。</param>
|
||||
/// <param name="shader">TShader。</param>
|
||||
public void AddShader(ActorShaderEnvType shaderType, TShader shader)
|
||||
{
|
||||
_allShader[(int)shaderType] = shader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据当前环境获取Shader。
|
||||
/// </summary>
|
||||
/// <param name="type">当前环境类型。</param>
|
||||
/// <returns>TShader。</returns>
|
||||
public TShader GetShader(ActorShaderEnvType type)
|
||||
{
|
||||
return _allShader[(int)type];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否符合shader集合。
|
||||
/// </summary>
|
||||
/// <param name="shader">Shader实例。</param>
|
||||
/// <returns>是否符合。</returns>
|
||||
public bool IsMatch(Shader shader)
|
||||
{
|
||||
foreach (var dodShader in _allShader)
|
||||
{
|
||||
if (dodShader != null && dodShader.Shader == shader)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79b6e5be73e14c929b6a3b4a980976ac
|
||||
timeCreated: 1701916950
|
@@ -1,117 +0,0 @@
|
||||
using GameBase;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
enum ActorShaderGroupType
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用的角色shader
|
||||
/// </summary>
|
||||
Brdf = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 眼睛
|
||||
/// </summary>
|
||||
BrdfEye,
|
||||
|
||||
///可能后面扩展,比如特效的特殊角色材质
|
||||
GroupMax,
|
||||
}
|
||||
|
||||
enum ActorShaderEnvType
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏内场景默认模型,不带阴影,不带xray,不透明效果
|
||||
/// </summary>
|
||||
EnvNormal = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 展示场景
|
||||
/// </summary>
|
||||
EnvShow,
|
||||
|
||||
/// <summary>
|
||||
/// 带阴影
|
||||
/// </summary>
|
||||
EnvShadow,
|
||||
|
||||
/// <summary>
|
||||
/// 带xray,默认也带Shadow
|
||||
/// </summary>
|
||||
EnvXRay,
|
||||
|
||||
/// <summary>
|
||||
/// 透明渐隐效果
|
||||
/// </summary>
|
||||
EnvAlphaFade,
|
||||
|
||||
/// <summary>
|
||||
/// 展示场景没shadow
|
||||
/// </summary>
|
||||
EnvShow_NoShadow,
|
||||
|
||||
EnvTypeMax
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 角色Shader管理器。
|
||||
/// </summary>
|
||||
class ActorShaderMgr : Singleton<ActorShaderMgr>
|
||||
{
|
||||
private readonly ActorShaderGroup[] _allShaderGroup = new ActorShaderGroup[(int)ActorShaderGroupType.GroupMax];
|
||||
|
||||
public ActorShaderMgr()
|
||||
{
|
||||
CreateBrdfShader();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据当前Render查找角色的Shader分组。
|
||||
/// </summary>
|
||||
/// <param name="render">Render。</param>
|
||||
/// <returns>角色的Shader分组。</returns>
|
||||
public ActorShaderGroup FindShaderGroup(Renderer render)
|
||||
{
|
||||
var sharedMat = render.sharedMaterial;
|
||||
if (sharedMat == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var shader = sharedMat.shader;
|
||||
foreach (var group in _allShaderGroup)
|
||||
{
|
||||
if (group != null && group.IsMatch(shader))
|
||||
{
|
||||
return group;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void CreateBrdfShader()
|
||||
{
|
||||
//通用的效果
|
||||
var actorShader = new ActorShaderGroup();
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvNormal, new TShader("TEngine/Actor/ActorBrdf",shaderLocation:"ActorBrdf"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvShow, new TShader("TEngine/Actor/Show/ActorBrdf",shaderLocation:"ActorBrdf_Show"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvShow_NoShadow, new TShader("TEngine/Actor/Show/ActorBrdf_NoShadow",shaderLocation:"ActorBrdf_NoShadow"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvShadow, new TShader("TEngine/Actor/ActorBrdf",shaderLocation:"ActorBrdf_Normal"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvXRay, new TShader("TEngine/Actor/X-Ray",shaderLocation:"X-Ray"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvAlphaFade, new TShader("TEngine/Actor/Fade/ActorBrdf",shaderLocation:"ActorBrdf_Fade"));
|
||||
_allShaderGroup[(int)ActorShaderGroupType.Brdf] = actorShader;
|
||||
|
||||
|
||||
//眼睛效果
|
||||
actorShader = new ActorShaderGroup();
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvNormal, new TShader("TEngine/Actor/ActorEye",shaderLocation:"ActorEye"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvShow, new TShader("TEngine/Actor/Show/ActorEye",shaderLocation:"ActorEye_Show", "MRT_DISABLE", "MRT_ENABLE"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvShadow, new TShader("TEngine/Actor/ActorEye",shaderLocation:"ActorEye"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvXRay, new TShader("TEngine/Actor/ActorEye",shaderLocation:"ActorEye"));
|
||||
actorShader.AddShader(ActorShaderEnvType.EnvAlphaFade, new TShader("TEngine/Actor/Fade/ActorEye",shaderLocation:"ActorEye_Fade"));
|
||||
|
||||
_allShaderGroup[(int)ActorShaderGroupType.BrdfEye] = actorShader;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a38b9b4bee84fabb1ef8db5292a6db6
|
||||
timeCreated: 1701916853
|
@@ -1,154 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// TShader scripts used for all rendering.
|
||||
/// <remarks>统一封装对shader的管理。</remarks>
|
||||
/// </summary>
|
||||
public class TShader
|
||||
{
|
||||
private bool _loaded;
|
||||
private Shader _shader;
|
||||
private readonly string _shaderName;
|
||||
private readonly string _shaderLocation;
|
||||
private readonly List<string> _keywordOn = new List<string>();
|
||||
private readonly List<string> _keywordOff = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Shader scripts used for all rendering.
|
||||
/// </summary>
|
||||
public Shader Shader
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_loaded)
|
||||
{
|
||||
_loaded = true;
|
||||
_shader = FindShader(_shaderLocation,_shaderName);
|
||||
|
||||
if (_shader == null)
|
||||
{
|
||||
Log.Error($"invalid shader path: {_shaderLocation}, shader name {_shaderName}");
|
||||
}
|
||||
}
|
||||
|
||||
return _shader;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找Shader。
|
||||
/// </summary>
|
||||
/// <param name="shaderLocation">Shader定位地址。</param>
|
||||
/// <param name="shaderName">Shader名称。</param>
|
||||
/// <returns>Shader实例。</returns>
|
||||
public static Shader FindShader(string shaderLocation,string shaderName)
|
||||
{
|
||||
Shader shader = GameModule.Resource.LoadAsset<Shader>(shaderLocation);
|
||||
if (shader != null)
|
||||
{
|
||||
return shader;
|
||||
}
|
||||
return Shader.Find(shaderName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TShader构造函数。
|
||||
/// </summary>
|
||||
/// <param name="shaderName">shader名称。</param>
|
||||
/// <param name="shaderLocation">shader路径。</param>
|
||||
public TShader(string shaderName, string shaderLocation)
|
||||
{
|
||||
_shaderName = shaderName;
|
||||
_shaderLocation = shaderLocation;
|
||||
_shader = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TShader构造函数。
|
||||
/// </summary>
|
||||
/// <param name="shaderName">shader名称。</param>
|
||||
/// <param name="shaderLocation">shader路径。</param>
|
||||
/// <param name="keywordOn">开启选项。</param>
|
||||
/// <param name="keywordOff">关闭选项。</param>
|
||||
public TShader(string shaderName, string shaderLocation, string keywordOn, string keywordOff)
|
||||
{
|
||||
_shaderName = shaderName;
|
||||
_shaderLocation = shaderLocation;
|
||||
_shader = null;
|
||||
_keywordOn.Add(keywordOn);
|
||||
_keywordOff.Add(keywordOff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TShader构造函数。
|
||||
/// </summary>
|
||||
/// <param name="shaderName">shader名称。</param>
|
||||
/// <param name="shaderLocation">shader路径。</param>
|
||||
/// <param name="keywordOn">开启选项。</param>
|
||||
/// <param name="keywordOff">关闭选项。</param>
|
||||
public TShader(string shaderName, string shaderLocation, string[] keywordOn, string[] keywordOff)
|
||||
{
|
||||
_shaderName = shaderName;
|
||||
_shaderLocation = shaderLocation;
|
||||
_shader = null;
|
||||
_keywordOn.AddRange(keywordOn);
|
||||
_keywordOff.AddRange(keywordOff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Shader效果。
|
||||
/// </summary>
|
||||
/// <param name="render">渲染对象。</param>
|
||||
public void ApplyRender(Renderer render)
|
||||
{
|
||||
var sharedMat = render.sharedMaterial;
|
||||
if (sharedMat != null)
|
||||
{
|
||||
//copy一份材质
|
||||
sharedMat = render.material;
|
||||
sharedMat.shader = Shader;
|
||||
|
||||
foreach (var keyword in _keywordOff)
|
||||
{
|
||||
sharedMat.DisableKeyword(keyword);
|
||||
}
|
||||
|
||||
foreach (var keyword in _keywordOn)
|
||||
{
|
||||
sharedMat.EnableKeyword(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除shader。
|
||||
/// </summary>
|
||||
/// <param name="render">渲染对象。</param>
|
||||
public void ClearRender(Renderer render)
|
||||
{
|
||||
if (_keywordOff.Count <= 0 && _keywordOn.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sharedMat = render.sharedMaterial;
|
||||
if (sharedMat != null)
|
||||
{
|
||||
//copy一份材质。
|
||||
sharedMat = render.material;
|
||||
for (int k = 0; k < _keywordOn.Count; k++)
|
||||
{
|
||||
sharedMat.DisableKeyword(_keywordOn[k]);
|
||||
}
|
||||
|
||||
for (int k = 0; k < _keywordOff.Count; k++)
|
||||
{
|
||||
sharedMat.EnableKeyword(_keywordOff[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e219233984c14f7d97bc744c07fe13d0
|
||||
timeCreated: 1698115491
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a214e54975b4d7da2d804f869524801
|
||||
timeCreated: 1695289293
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0615e8b32d534bc48a60e42c973053ad
|
||||
timeCreated: 1695289443
|
@@ -1,84 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class ClickEventListener : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
public static ClickEventListener Get(GameObject obj)
|
||||
{
|
||||
ClickEventListener listener = obj.GetComponent<ClickEventListener>();
|
||||
if (listener == null)
|
||||
{
|
||||
listener = obj.AddComponent<ClickEventListener>();
|
||||
}
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
private System.Action<GameObject> _clickedHandler = null;
|
||||
private System.Action<GameObject> _doubleClickedHandler = null;
|
||||
private System.Action<GameObject> _onPointerDownHandler = null;
|
||||
private System.Action<GameObject> _onPointerUpHandler = null;
|
||||
bool _isPressed = false;
|
||||
|
||||
public bool IsPressed => _isPressed;
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.clickCount == 2)
|
||||
{
|
||||
if (_doubleClickedHandler != null)
|
||||
{
|
||||
_doubleClickedHandler(gameObject);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_clickedHandler != null)
|
||||
{
|
||||
_clickedHandler(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClickEventHandler(System.Action<GameObject> handler)
|
||||
{
|
||||
_clickedHandler = handler;
|
||||
}
|
||||
|
||||
public void SetDoubleClickEventHandler(System.Action<GameObject> handler)
|
||||
{
|
||||
_doubleClickedHandler = handler;
|
||||
}
|
||||
|
||||
public void SetPointerDownHandler(System.Action<GameObject> handler)
|
||||
{
|
||||
_onPointerDownHandler = handler;
|
||||
}
|
||||
|
||||
public void SetPointerUpHandler(System.Action<GameObject> handler)
|
||||
{
|
||||
_onPointerUpHandler = handler;
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
_isPressed = true;
|
||||
if (_onPointerDownHandler != null)
|
||||
{
|
||||
_onPointerDownHandler(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
_isPressed = false;
|
||||
if (_onPointerUpHandler != null)
|
||||
{
|
||||
_onPointerUpHandler(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
||||
public enum SnapStatus
|
||||
{
|
||||
NoTargetSet = 0,
|
||||
TargetHasSet = 1,
|
||||
SnapMoving = 2,
|
||||
SnapMoveFinish = 3
|
||||
}
|
||||
|
||||
|
||||
public enum ItemCornerEnum
|
||||
{
|
||||
LeftBottom = 0,
|
||||
LeftTop,
|
||||
RightTop,
|
||||
RightBottom,
|
||||
}
|
||||
|
||||
|
||||
public enum ListItemArrangeType
|
||||
{
|
||||
TopToBottom = 0,
|
||||
BottomToTop,
|
||||
LeftToRight,
|
||||
RightToLeft,
|
||||
}
|
||||
|
||||
public enum GridItemArrangeType
|
||||
{
|
||||
TopLeftToBottomRight = 0,
|
||||
BottomLeftToTopRight,
|
||||
TopRightToBottomLeft,
|
||||
BottomRightToTopLeft,
|
||||
}
|
||||
public enum GridFixedType
|
||||
{
|
||||
ColumnCountFixed = 0,
|
||||
RowCountFixed,
|
||||
}
|
||||
|
||||
public struct RowColumnPair
|
||||
{
|
||||
public RowColumnPair(int row1, int column1)
|
||||
{
|
||||
mRow = row1;
|
||||
mColumn = column1;
|
||||
}
|
||||
|
||||
public bool Equals(RowColumnPair other)
|
||||
{
|
||||
return this.mRow == other.mRow && this.mColumn == other.mColumn;
|
||||
}
|
||||
|
||||
public static bool operator ==(RowColumnPair a, RowColumnPair b)
|
||||
{
|
||||
return (a.mRow == b.mRow)&&(a.mColumn == b.mColumn);
|
||||
}
|
||||
public static bool operator !=(RowColumnPair a, RowColumnPair b)
|
||||
{
|
||||
return (a.mRow != b.mRow) || (a.mColumn != b.mColumn); ;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (obj is RowColumnPair) && Equals((RowColumnPair)obj);
|
||||
}
|
||||
|
||||
|
||||
public int mRow;
|
||||
public int mColumn;
|
||||
}
|
||||
}
|
@@ -1,326 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class ItemSizeGroup
|
||||
{
|
||||
public float[] ItemSizeArray = null;
|
||||
public float[] ItemStartPosArray = null;
|
||||
public int ItemCount = 0;
|
||||
private int _dirtyBeginIndex = ItemPosMgr.ItemMaxCountPerGroup;
|
||||
public float GroupSize = 0;
|
||||
public float GroupStartPos = 0;
|
||||
public float GroupEndPos = 0;
|
||||
public int GroupIndex = 0;
|
||||
public float ItemDefaultSize = 0;
|
||||
|
||||
public ItemSizeGroup(int index, float itemDefaultSize)
|
||||
{
|
||||
GroupIndex = index;
|
||||
ItemDefaultSize = itemDefaultSize;
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
ItemSizeArray = new float[ItemPosMgr.ItemMaxCountPerGroup];
|
||||
if (ItemDefaultSize != 0)
|
||||
{
|
||||
for (int i = 0; i < ItemSizeArray.Length; ++i)
|
||||
{
|
||||
ItemSizeArray[i] = ItemDefaultSize;
|
||||
}
|
||||
}
|
||||
|
||||
ItemStartPosArray = new float[ItemPosMgr.ItemMaxCountPerGroup];
|
||||
ItemStartPosArray[0] = 0;
|
||||
ItemCount = ItemPosMgr.ItemMaxCountPerGroup;
|
||||
GroupSize = ItemDefaultSize * ItemSizeArray.Length;
|
||||
if (ItemDefaultSize != 0)
|
||||
{
|
||||
_dirtyBeginIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirtyBeginIndex = ItemPosMgr.ItemMaxCountPerGroup;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetItemStartPos(int index)
|
||||
{
|
||||
return GroupStartPos + ItemStartPosArray[index];
|
||||
}
|
||||
|
||||
public bool IsDirty
|
||||
{
|
||||
get { return (_dirtyBeginIndex < ItemCount); }
|
||||
}
|
||||
|
||||
public float SetItemSize(int index, float size)
|
||||
{
|
||||
float old = ItemSizeArray[index];
|
||||
if (Math.Abs(old - size) < 0.001f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemSizeArray[index] = size;
|
||||
if (index < _dirtyBeginIndex)
|
||||
{
|
||||
_dirtyBeginIndex = index;
|
||||
}
|
||||
|
||||
float ds = size - old;
|
||||
GroupSize = GroupSize + ds;
|
||||
return ds;
|
||||
}
|
||||
|
||||
public void SetItemCount(int count)
|
||||
{
|
||||
if (ItemCount == count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemCount = count;
|
||||
RecalcGroupSize();
|
||||
}
|
||||
|
||||
public void RecalcGroupSize()
|
||||
{
|
||||
GroupSize = 0;
|
||||
for (int i = 0; i < ItemCount; ++i)
|
||||
{
|
||||
GroupSize += ItemSizeArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
public int GetItemIndexByPos(float pos)
|
||||
{
|
||||
if (ItemCount == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int low = 0;
|
||||
int high = ItemCount - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
int mid = (low + high) / 2;
|
||||
float startPos = ItemStartPosArray[mid];
|
||||
float endPos = startPos + ItemSizeArray[mid];
|
||||
if (startPos <= pos && endPos >= pos)
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
else if (pos > endPos)
|
||||
{
|
||||
low = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void UpdateAllItemStartPos()
|
||||
{
|
||||
if (_dirtyBeginIndex >= ItemCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int startIndex = (_dirtyBeginIndex < 1) ? 1 : _dirtyBeginIndex;
|
||||
for (int i = startIndex; i < ItemCount; ++i)
|
||||
{
|
||||
ItemStartPosArray[i] = ItemStartPosArray[i - 1] + ItemSizeArray[i - 1];
|
||||
}
|
||||
|
||||
_dirtyBeginIndex = ItemCount;
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemPosMgr
|
||||
{
|
||||
public const int ItemMaxCountPerGroup = 100;
|
||||
readonly List<ItemSizeGroup> _itemSizeGroupList = new List<ItemSizeGroup>();
|
||||
public int _dirtyBeginIndex = int.MaxValue;
|
||||
public float TotalSize = 0;
|
||||
public float ItemDefaultSize = 20;
|
||||
|
||||
public ItemPosMgr(float itemDefaultSize)
|
||||
{
|
||||
ItemDefaultSize = itemDefaultSize;
|
||||
}
|
||||
|
||||
public void SetItemMaxCount(int maxCount)
|
||||
{
|
||||
_dirtyBeginIndex = 0;
|
||||
TotalSize = 0;
|
||||
int st = maxCount % ItemMaxCountPerGroup;
|
||||
int lastGroupItemCount = st;
|
||||
int needMaxGroupCount = maxCount / ItemMaxCountPerGroup;
|
||||
if (st > 0)
|
||||
{
|
||||
needMaxGroupCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastGroupItemCount = ItemMaxCountPerGroup;
|
||||
}
|
||||
|
||||
int count = _itemSizeGroupList.Count;
|
||||
if (count > needMaxGroupCount)
|
||||
{
|
||||
int d = count - needMaxGroupCount;
|
||||
_itemSizeGroupList.RemoveRange(needMaxGroupCount, d);
|
||||
}
|
||||
else if (count < needMaxGroupCount)
|
||||
{
|
||||
int d = needMaxGroupCount - count;
|
||||
for (int i = 0; i < d; ++i)
|
||||
{
|
||||
ItemSizeGroup tGroup = new ItemSizeGroup(count + i, ItemDefaultSize);
|
||||
_itemSizeGroupList.Add(tGroup);
|
||||
}
|
||||
}
|
||||
|
||||
count = _itemSizeGroupList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count - 1; ++i)
|
||||
{
|
||||
_itemSizeGroupList[i].SetItemCount(ItemMaxCountPerGroup);
|
||||
}
|
||||
|
||||
_itemSizeGroupList[count - 1].SetItemCount(lastGroupItemCount);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
TotalSize = TotalSize + _itemSizeGroupList[i].GroupSize;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetItemSize(int itemIndex, float size)
|
||||
{
|
||||
int groupIndex = itemIndex / ItemMaxCountPerGroup;
|
||||
int indexInGroup = itemIndex % ItemMaxCountPerGroup;
|
||||
ItemSizeGroup tGroup = _itemSizeGroupList[groupIndex];
|
||||
float changedSize = tGroup.SetItemSize(indexInGroup, size);
|
||||
if (changedSize != 0f)
|
||||
{
|
||||
if (groupIndex < _dirtyBeginIndex)
|
||||
{
|
||||
_dirtyBeginIndex = groupIndex;
|
||||
}
|
||||
}
|
||||
|
||||
TotalSize += changedSize;
|
||||
}
|
||||
|
||||
public float GetItemPos(int itemIndex)
|
||||
{
|
||||
Update(true);
|
||||
int groupIndex = itemIndex / ItemMaxCountPerGroup;
|
||||
int indexInGroup = itemIndex % ItemMaxCountPerGroup;
|
||||
return _itemSizeGroupList[groupIndex].GetItemStartPos(indexInGroup);
|
||||
}
|
||||
|
||||
public void GetItemIndexAndPosAtGivenPos(float pos, ref int index, ref float itemPos)
|
||||
{
|
||||
Update(true);
|
||||
index = 0;
|
||||
itemPos = 0f;
|
||||
int count = _itemSizeGroupList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemSizeGroup hitGroup = null;
|
||||
|
||||
int low = 0;
|
||||
int high = count - 1;
|
||||
while (low <= high)
|
||||
{
|
||||
int mid = (low + high) / 2;
|
||||
ItemSizeGroup tGroup = _itemSizeGroupList[mid];
|
||||
if (tGroup.GroupStartPos <= pos && tGroup.GroupEndPos >= pos)
|
||||
{
|
||||
hitGroup = tGroup;
|
||||
break;
|
||||
}
|
||||
else if (pos > tGroup.GroupEndPos)
|
||||
{
|
||||
low = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int hitIndex = -1;
|
||||
if (hitGroup != null)
|
||||
{
|
||||
hitIndex = hitGroup.GetItemIndexByPos(pos - hitGroup.GroupStartPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hitIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
index = hitIndex + hitGroup.GroupIndex * ItemMaxCountPerGroup;
|
||||
itemPos = hitGroup.GetItemStartPos(hitIndex);
|
||||
}
|
||||
|
||||
public void Update(bool updateAll)
|
||||
{
|
||||
int count = _itemSizeGroupList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dirtyBeginIndex >= count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int loopCount = 0;
|
||||
for (int i = _dirtyBeginIndex; i < count; ++i)
|
||||
{
|
||||
loopCount++;
|
||||
ItemSizeGroup tGroup = _itemSizeGroupList[i];
|
||||
_dirtyBeginIndex++;
|
||||
tGroup.UpdateAllItemStartPos();
|
||||
if (i == 0)
|
||||
{
|
||||
tGroup.GroupStartPos = 0;
|
||||
tGroup.GroupEndPos = tGroup.GroupSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
tGroup.GroupStartPos = _itemSizeGroupList[i - 1].GroupEndPos;
|
||||
tGroup.GroupEndPos = tGroup.GroupStartPos + tGroup.GroupSize;
|
||||
}
|
||||
|
||||
if (!updateAll && loopCount > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
namespace GameLogic
|
||||
{
|
||||
//if GridFixedType is GridFixedType.ColumnCountFixed, then the GridItemGroup is one row of the gridview
|
||||
//if GridFixedType is GridFixedType.RowCountFixed, then the GridItemGroup is one column of the gridview
|
||||
public class GridItemGroup
|
||||
{
|
||||
private int _count = 0;
|
||||
private int _groupIndex = -1;//the row index or the column index of this group
|
||||
private LoopGridViewItem _first = null;
|
||||
private LoopGridViewItem _last = null;
|
||||
public int Count => _count;
|
||||
|
||||
public LoopGridViewItem First => _first;
|
||||
|
||||
public LoopGridViewItem Last => _last;
|
||||
|
||||
public int GroupIndex
|
||||
{
|
||||
get => _groupIndex;
|
||||
set => _groupIndex = value;
|
||||
}
|
||||
|
||||
|
||||
public LoopGridViewItem GetItemByColumn(int column)
|
||||
{
|
||||
LoopGridViewItem cur = _first;
|
||||
while(cur != null)
|
||||
{
|
||||
if(cur.Column == column)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
cur = cur.NextItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public LoopGridViewItem GetItemByRow(int row)
|
||||
{
|
||||
LoopGridViewItem cur = _first;
|
||||
while (cur != null)
|
||||
{
|
||||
if (cur.Row == row)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
cur = cur.NextItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void ReplaceItem(LoopGridViewItem curItem,LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = curItem.PrevItem;
|
||||
newItem.NextItem = curItem.NextItem;
|
||||
if(newItem.PrevItem != null)
|
||||
{
|
||||
newItem.PrevItem.NextItem = newItem;
|
||||
}
|
||||
if(newItem.NextItem != null)
|
||||
{
|
||||
newItem.NextItem.PrevItem = newItem;
|
||||
}
|
||||
if(_first == curItem)
|
||||
{
|
||||
_first = newItem;
|
||||
}
|
||||
if(_last == curItem)
|
||||
{
|
||||
_last = newItem;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddFirst(LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = null;
|
||||
if (_first == null)
|
||||
{
|
||||
_first = newItem;
|
||||
_last = newItem;
|
||||
_first.PrevItem = null;
|
||||
_first.NextItem = null;
|
||||
_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_first.PrevItem = newItem;
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = _first;
|
||||
_first = newItem;
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddLast(LoopGridViewItem newItem)
|
||||
{
|
||||
newItem.PrevItem = null;
|
||||
newItem.NextItem = null;
|
||||
if (_first == null)
|
||||
{
|
||||
_first = newItem;
|
||||
_last = newItem;
|
||||
_first.PrevItem = null;
|
||||
_first.NextItem = null;
|
||||
_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_last.NextItem = newItem;
|
||||
newItem.PrevItem = _last;
|
||||
newItem.NextItem = null;
|
||||
_last = newItem;
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridViewItem RemoveFirst()
|
||||
{
|
||||
LoopGridViewItem ret = _first;
|
||||
if (_first == null)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if(_first == _last)
|
||||
{
|
||||
_first = null;
|
||||
_last = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
_first = _first.NextItem;
|
||||
_first.PrevItem = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
public LoopGridViewItem RemoveLast()
|
||||
{
|
||||
LoopGridViewItem ret = _last;
|
||||
if (_first == null)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (_first == _last)
|
||||
{
|
||||
_first = null;
|
||||
_last = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
_last = _last.PrevItem;
|
||||
_last.NextItem = null;
|
||||
--_count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
LoopGridViewItem current = _first;
|
||||
while (current != null)
|
||||
{
|
||||
current.PrevItem = null;
|
||||
current.NextItem = null;
|
||||
current = current.NextItem;
|
||||
}
|
||||
_first = null;
|
||||
_last = null;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,113 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class GridItemPool
|
||||
{
|
||||
private GameObject _prefabObj;
|
||||
private string _prefabName;
|
||||
private int _initCreateCount = 1;
|
||||
private readonly List<LoopGridViewItem> _tmpPooledItemList = new List<LoopGridViewItem>();
|
||||
private readonly List<LoopGridViewItem> _pooledItemList = new List<LoopGridViewItem>();
|
||||
private static int _curItemIdCount = 0;
|
||||
private RectTransform _itemParent = null;
|
||||
public GridItemPool()
|
||||
{
|
||||
|
||||
}
|
||||
public void Init(GameObject prefabObj, int createCount, RectTransform parent)
|
||||
{
|
||||
_prefabObj = prefabObj;
|
||||
_prefabName = _prefabObj.name;
|
||||
_initCreateCount = createCount;
|
||||
_itemParent = parent;
|
||||
_prefabObj.SetActive(false);
|
||||
for (int i = 0; i < _initCreateCount; ++i)
|
||||
{
|
||||
LoopGridViewItem tViewItem = CreateItem();
|
||||
RecycleItemReal(tViewItem);
|
||||
}
|
||||
}
|
||||
public LoopGridViewItem GetItem()
|
||||
{
|
||||
_curItemIdCount++;
|
||||
LoopGridViewItem tItem = null;
|
||||
if (_tmpPooledItemList.Count > 0)
|
||||
{
|
||||
int count = _tmpPooledItemList.Count;
|
||||
tItem = _tmpPooledItemList[count - 1];
|
||||
_tmpPooledItemList.RemoveAt(count - 1);
|
||||
tItem.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = _pooledItemList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
tItem = CreateItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
tItem = _pooledItemList[count - 1];
|
||||
_pooledItemList.RemoveAt(count - 1);
|
||||
tItem.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
tItem.ItemId = _curItemIdCount;
|
||||
return tItem;
|
||||
|
||||
}
|
||||
|
||||
public void DestroyAllItem()
|
||||
{
|
||||
ClearTmpRecycledItem();
|
||||
int count = _pooledItemList.Count;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
GameObject.DestroyImmediate(_pooledItemList[i].gameObject);
|
||||
}
|
||||
_pooledItemList.Clear();
|
||||
}
|
||||
public LoopGridViewItem CreateItem()
|
||||
{
|
||||
|
||||
GameObject go = GameObject.Instantiate<GameObject>(_prefabObj, Vector3.zero, Quaternion.identity, _itemParent);
|
||||
go.SetActive(true);
|
||||
RectTransform rf = go.GetComponent<RectTransform>();
|
||||
rf.localScale = Vector3.one;
|
||||
rf.anchoredPosition3D = Vector3.zero;
|
||||
rf.localEulerAngles = Vector3.zero;
|
||||
LoopGridViewItem tViewItem = go.GetComponent<LoopGridViewItem>();
|
||||
tViewItem.ItemPrefabName = _prefabName;
|
||||
tViewItem.GoId = go.GetHashCode();
|
||||
return tViewItem;
|
||||
}
|
||||
void RecycleItemReal(LoopGridViewItem item)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
_pooledItemList.Add(item);
|
||||
}
|
||||
public void RecycleItem(LoopGridViewItem item)
|
||||
{
|
||||
item.PrevItem = null;
|
||||
item.NextItem = null;
|
||||
_tmpPooledItemList.Add(item);
|
||||
}
|
||||
public void ClearTmpRecycledItem()
|
||||
{
|
||||
int count = _tmpPooledItemList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
RecycleItemReal(_tmpPooledItemList[i]);
|
||||
}
|
||||
_tmpPooledItemList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,184 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
||||
public class LoopGridViewItem : MonoBehaviour
|
||||
{
|
||||
// indicates the item’s index in the list the mItemIndex can only be from 0 to itemTotalCount -1.
|
||||
int mItemIndex = -1;
|
||||
// the row index, the item is in. starting from 0.
|
||||
int mRow = -1;
|
||||
// the column index, the item is in. starting from 0.
|
||||
int mColumn = -1;
|
||||
//indicates the item’s id.
|
||||
//This property is set when the item is created or fetched from pool,
|
||||
//and will no longer change until the item is recycled back to pool.
|
||||
int mItemId = -1;
|
||||
|
||||
private int _goId = 0;
|
||||
|
||||
public int GoId
|
||||
{
|
||||
set => _goId = value;
|
||||
get => _goId;
|
||||
}
|
||||
|
||||
LoopGridView mParentGridView = null;
|
||||
bool mIsInitHandlerCalled = false;
|
||||
string mItemPrefabName;
|
||||
RectTransform mCachedRectTransform;
|
||||
int mItemCreatedCheckFrameCount = 0;
|
||||
|
||||
object mUserObjectData = null;
|
||||
int mUserIntData1 = 0;
|
||||
int mUserIntData2 = 0;
|
||||
string mUserStringData1 = null;
|
||||
string mUserStringData2 = null;
|
||||
|
||||
LoopGridViewItem mPrevItem;
|
||||
LoopGridViewItem mNextItem;
|
||||
|
||||
public object UserObjectData
|
||||
{
|
||||
get { return mUserObjectData; }
|
||||
set { mUserObjectData = value; }
|
||||
}
|
||||
public int UserIntData1
|
||||
{
|
||||
get { return mUserIntData1; }
|
||||
set { mUserIntData1 = value; }
|
||||
}
|
||||
public int UserIntData2
|
||||
{
|
||||
get { return mUserIntData2; }
|
||||
set { mUserIntData2 = value; }
|
||||
}
|
||||
public string UserStringData1
|
||||
{
|
||||
get { return mUserStringData1; }
|
||||
set { mUserStringData1 = value; }
|
||||
}
|
||||
public string UserStringData2
|
||||
{
|
||||
get { return mUserStringData2; }
|
||||
set { mUserStringData2 = value; }
|
||||
}
|
||||
|
||||
public int ItemCreatedCheckFrameCount
|
||||
{
|
||||
get { return mItemCreatedCheckFrameCount; }
|
||||
set { mItemCreatedCheckFrameCount = value; }
|
||||
}
|
||||
|
||||
|
||||
public RectTransform CachedRectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mCachedRectTransform == null)
|
||||
{
|
||||
mCachedRectTransform = gameObject.GetComponent<RectTransform>();
|
||||
}
|
||||
return mCachedRectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
public string ItemPrefabName
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemPrefabName;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemPrefabName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Row
|
||||
{
|
||||
get
|
||||
{
|
||||
return mRow;
|
||||
}
|
||||
set
|
||||
{
|
||||
mRow = value;
|
||||
}
|
||||
}
|
||||
public int Column
|
||||
{
|
||||
get
|
||||
{
|
||||
return mColumn;
|
||||
}
|
||||
set
|
||||
{
|
||||
mColumn = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ItemIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemIndex = value;
|
||||
}
|
||||
}
|
||||
public int ItemId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mItemId;
|
||||
}
|
||||
set
|
||||
{
|
||||
mItemId = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool IsInitHandlerCalled
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIsInitHandlerCalled;
|
||||
}
|
||||
set
|
||||
{
|
||||
mIsInitHandlerCalled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridView ParentGridView
|
||||
{
|
||||
get
|
||||
{
|
||||
return mParentGridView;
|
||||
}
|
||||
set
|
||||
{
|
||||
mParentGridView = value;
|
||||
}
|
||||
}
|
||||
|
||||
public LoopGridViewItem PrevItem
|
||||
{
|
||||
get { return mPrevItem; }
|
||||
set { mPrevItem = value; }
|
||||
}
|
||||
public LoopGridViewItem NextItem
|
||||
{
|
||||
get { return mNextItem; }
|
||||
set { mNextItem = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec0432517adfcb84bb6163d7a44ab8c1
|
||||
timeCreated: 1554538573
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9bbd48a4abc45c46a92b92d0df3ae07
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,216 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class LoopListViewItem : MonoBehaviour
|
||||
{
|
||||
public float Padding;
|
||||
|
||||
private int _itemIndex = -1;
|
||||
private int _itemId = -1;
|
||||
private LoopListView _parentListView = null;
|
||||
private bool _isInitHandlerCalled = false;
|
||||
private string _itemPrefabName;
|
||||
private RectTransform _cachedRectTransform;
|
||||
private float _padding;
|
||||
private float _distanceWithViewPortSnapCenter = 0;
|
||||
private int _itemCreatedCheckFrameCount = 0;
|
||||
private float _startPosOffset = 0;
|
||||
|
||||
private object _userObjectData = null;
|
||||
private int _userIntData1 = 0;
|
||||
private int _userIntData2 = 0;
|
||||
private string _userStringData1 = null;
|
||||
private string _userStringData2 = null;
|
||||
|
||||
private int _goId = 0;
|
||||
|
||||
public int GoId
|
||||
{
|
||||
set => _goId = value;
|
||||
get => _goId;
|
||||
}
|
||||
|
||||
public object UserObjectData
|
||||
{
|
||||
get => _userObjectData;
|
||||
set => _userObjectData = value;
|
||||
}
|
||||
|
||||
public int UserIntData1
|
||||
{
|
||||
get => _userIntData1;
|
||||
set => _userIntData1 = value;
|
||||
}
|
||||
|
||||
public int UserIntData2
|
||||
{
|
||||
get => _userIntData2;
|
||||
set => _userIntData2 = value;
|
||||
}
|
||||
|
||||
public string UserStringData1
|
||||
{
|
||||
get => _userStringData1;
|
||||
set => _userStringData1 = value;
|
||||
}
|
||||
|
||||
public string UserStringData2
|
||||
{
|
||||
get => _userStringData2;
|
||||
set => _userStringData2 = value;
|
||||
}
|
||||
|
||||
public float DistanceWithViewPortSnapCenter
|
||||
{
|
||||
get => _distanceWithViewPortSnapCenter;
|
||||
set => _distanceWithViewPortSnapCenter = value;
|
||||
}
|
||||
|
||||
public float StartPosOffset
|
||||
{
|
||||
get => _startPosOffset;
|
||||
set => _startPosOffset = value;
|
||||
}
|
||||
|
||||
public int ItemCreatedCheckFrameCount
|
||||
{
|
||||
get => _itemCreatedCheckFrameCount;
|
||||
set => _itemCreatedCheckFrameCount = value;
|
||||
}
|
||||
|
||||
public RectTransform CachedRectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cachedRectTransform == null)
|
||||
{
|
||||
_cachedRectTransform = gameObject.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
return _cachedRectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
public string ItemPrefabName
|
||||
{
|
||||
get => _itemPrefabName;
|
||||
set => _itemPrefabName = value;
|
||||
}
|
||||
|
||||
public int ItemIndex
|
||||
{
|
||||
get => _itemIndex;
|
||||
set => _itemIndex = value;
|
||||
}
|
||||
|
||||
public int ItemId
|
||||
{
|
||||
get => _itemId;
|
||||
set => _itemId = value;
|
||||
}
|
||||
|
||||
|
||||
public bool IsInitHandlerCalled
|
||||
{
|
||||
get => _isInitHandlerCalled;
|
||||
set => _isInitHandlerCalled = value;
|
||||
}
|
||||
|
||||
public LoopListView ParentListView
|
||||
{
|
||||
get => _parentListView;
|
||||
set => _parentListView = value;
|
||||
}
|
||||
|
||||
public float TopY
|
||||
{
|
||||
get
|
||||
{
|
||||
ListItemArrangeType arrageType = ParentListView.ArrangeType;
|
||||
if (arrageType == ListItemArrangeType.TopToBottom)
|
||||
{
|
||||
return CachedRectTransform.localPosition.y;
|
||||
}
|
||||
else if (arrageType == ListItemArrangeType.BottomToTop)
|
||||
{
|
||||
return CachedRectTransform.localPosition.y + CachedRectTransform.rect.height;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public float BottomY
|
||||
{
|
||||
get
|
||||
{
|
||||
ListItemArrangeType arrageType = ParentListView.ArrangeType;
|
||||
if (arrageType == ListItemArrangeType.TopToBottom)
|
||||
{
|
||||
return CachedRectTransform.localPosition.y - CachedRectTransform.rect.height;
|
||||
}
|
||||
else if (arrageType == ListItemArrangeType.BottomToTop)
|
||||
{
|
||||
return CachedRectTransform.localPosition.y;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public float LeftX
|
||||
{
|
||||
get
|
||||
{
|
||||
ListItemArrangeType arrageType = ParentListView.ArrangeType;
|
||||
if (arrageType == ListItemArrangeType.LeftToRight)
|
||||
{
|
||||
return CachedRectTransform.localPosition.x;
|
||||
}
|
||||
else if (arrageType == ListItemArrangeType.RightToLeft)
|
||||
{
|
||||
return CachedRectTransform.localPosition.x - CachedRectTransform.rect.width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public float RightX
|
||||
{
|
||||
get
|
||||
{
|
||||
ListItemArrangeType arrageType = ParentListView.ArrangeType;
|
||||
if (arrageType == ListItemArrangeType.LeftToRight)
|
||||
{
|
||||
return CachedRectTransform.localPosition.x + CachedRectTransform.rect.width;
|
||||
}
|
||||
else if (arrageType == ListItemArrangeType.RightToLeft)
|
||||
{
|
||||
return CachedRectTransform.localPosition.x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public float ItemSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ParentListView.IsVertList)
|
||||
{
|
||||
return CachedRectTransform.rect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CachedRectTransform.rect.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float ItemSizeWithPadding => ItemSize + _padding;
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f3fbd5ce2514056b72986a6dea2aec2
|
||||
timeCreated: 1695289443
|
@@ -1,71 +0,0 @@
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 子界面之间共享的数据。
|
||||
/// </summary>
|
||||
public class ChildPageSharData
|
||||
{
|
||||
private object[] m_arrParams = new object[3]; // 共享参数列表
|
||||
|
||||
public object Param1 { get { return m_arrParams[0]; } }
|
||||
public object Param2 { get { return m_arrParams[1]; } }
|
||||
public object Param3 { get { return m_arrParams[2]; } }
|
||||
|
||||
/// <summary>
|
||||
/// 设置指定索引的参数。
|
||||
/// </summary>
|
||||
/// <param name="paramIdx"></param>
|
||||
/// <param name="param"></param>
|
||||
public void SetParam(int paramIdx, object param)
|
||||
{
|
||||
if (paramIdx >= m_arrParams.Length)
|
||||
return;
|
||||
|
||||
m_arrParams[paramIdx] = param;
|
||||
}
|
||||
}
|
||||
|
||||
public class ChildPageBase : UIWidget
|
||||
{
|
||||
|
||||
protected ChildPageSharData m_shareObjData; // 共享数据
|
||||
|
||||
// 初始化数据
|
||||
public void InitData(ChildPageSharData shareObjData)
|
||||
{
|
||||
m_shareObjData = shareObjData;
|
||||
}
|
||||
|
||||
public virtual void OnPageShowed(int oldShowType, int newShowType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 无参数刷新当前子界面
|
||||
// 收到那些数据变动的消息的时候使用
|
||||
public virtual void RefreshPage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public object ShareData1
|
||||
{
|
||||
get => m_shareObjData.Param1;
|
||||
set => m_shareObjData.SetParam(0, value);
|
||||
}
|
||||
|
||||
public object ShareData2
|
||||
{
|
||||
get => m_shareObjData.Param2;
|
||||
set => m_shareObjData.SetParam(1, value);
|
||||
}
|
||||
|
||||
public object ShareData3
|
||||
{
|
||||
get => m_shareObjData.Param3;
|
||||
set => m_shareObjData.SetParam(2, value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4b742d9af72478b9d6f7ebd2fa493a0
|
||||
timeCreated: 1687859782
|
@@ -1,457 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class SwitchPageMgr
|
||||
{
|
||||
private event Action<int, int> SwitchTabAction;
|
||||
|
||||
public delegate bool SwitchTabCondition(int selectId);
|
||||
|
||||
private SwitchTabCondition _switchTabCondition;
|
||||
|
||||
/// <summary>
|
||||
/// 页签Grid。
|
||||
/// </summary>
|
||||
protected Transform m_tabGrid;
|
||||
|
||||
/// <summary>
|
||||
/// 子UI父节点。
|
||||
/// </summary>
|
||||
public Transform ChildPageParent;
|
||||
|
||||
/// <summary>
|
||||
/// 存储子UI。
|
||||
/// </summary>
|
||||
private readonly Dictionary<int, List<string>> _switchPageDic = new Dictionary<int, List<string>>();
|
||||
|
||||
/// <summary>
|
||||
/// 子页签名字。
|
||||
/// </summary>
|
||||
private readonly List<string> _childPageNames = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 子页签字典。
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, ChildPageBase> _childPageDic = new Dictionary<string, ChildPageBase>();
|
||||
|
||||
/// <summary>
|
||||
/// 存储页签。
|
||||
/// </summary>
|
||||
private readonly Dictionary<int, SwitchTabItem> _tabDic = new Dictionary<int, SwitchTabItem>();
|
||||
|
||||
private readonly Dictionary<int, string> _tabName = new Dictionary<int, string>();
|
||||
|
||||
protected readonly List<int> IDList = new List<int>();
|
||||
|
||||
private readonly UIBase _owner;
|
||||
|
||||
protected int CurrentChildID = -100;
|
||||
|
||||
/// <summary>
|
||||
/// 需要设置显示隐藏。
|
||||
/// </summary>
|
||||
private readonly bool _needSetActive;
|
||||
|
||||
/// <summary>
|
||||
/// 子界面的共享数据。
|
||||
/// </summary>
|
||||
private readonly ChildPageSharData _shareData = new ChildPageSharData();
|
||||
|
||||
public object ShareData1 => _shareData.Param1;
|
||||
public object ShareData2 => _shareData.Param2;
|
||||
public object ShareData3 => _shareData.Param3;
|
||||
|
||||
public SwitchPageMgr(Transform grid, Transform childPageParent, UIBase owner, bool needSetActive = true)
|
||||
{
|
||||
m_tabGrid = grid;
|
||||
ChildPageParent = childPageParent;
|
||||
_owner = owner;
|
||||
_needSetActive = needSetActive;
|
||||
}
|
||||
|
||||
public void AddSwitchAction(Action<int, int> action)
|
||||
{
|
||||
SwitchTabAction += action;
|
||||
}
|
||||
|
||||
public void RemoveSwitchAction(Action<int, int> action)
|
||||
{
|
||||
SwitchTabAction -= action;
|
||||
}
|
||||
|
||||
public void AddSwitchCondition(SwitchTabCondition action)
|
||||
{
|
||||
_switchTabCondition = action;
|
||||
}
|
||||
|
||||
public void BindChildPage<T>(int childID) where T : ChildPageBase, new()
|
||||
{
|
||||
BindChildPage<T>(childID, string.Empty);
|
||||
}
|
||||
|
||||
public void BindChildPage<T>(int childID, string tabName) where T : ChildPageBase, new()
|
||||
{
|
||||
var pageName = typeof(T).Name;
|
||||
|
||||
if (IDList.IndexOf(childID) < 0)
|
||||
{
|
||||
IDList.Add(childID);
|
||||
}
|
||||
|
||||
if (!_childPageDic.ContainsKey(pageName))
|
||||
{
|
||||
_childPageDic[pageName] = new T();
|
||||
_childPageNames.Add(pageName);
|
||||
}
|
||||
|
||||
if (!_switchPageDic.ContainsKey(childID))
|
||||
{
|
||||
_switchPageDic[childID] = new List<string>();
|
||||
}
|
||||
|
||||
if (_switchPageDic[childID].IndexOf(pageName) < 0)
|
||||
{
|
||||
_switchPageDic[childID].Add(pageName);
|
||||
}
|
||||
|
||||
_tabName[childID] = tabName;
|
||||
}
|
||||
|
||||
public T CreatTab<T>(int initChildID, GameObject tabTemp = null) where T : SwitchTabItem, new()
|
||||
{
|
||||
T tab = null;
|
||||
for (var index = 0; index < IDList.Count; index++)
|
||||
{
|
||||
var childID = IDList[index];
|
||||
if (!_tabDic.ContainsKey(childID))
|
||||
{
|
||||
if (tabTemp != null)
|
||||
{
|
||||
tab = _owner.CreateWidgetByPrefab<T>(tabTemp, m_tabGrid);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab = _owner.CreateWidgetByType<T>(m_tabGrid);
|
||||
}
|
||||
|
||||
tab.UpdateTabName(_tabName[childID]);
|
||||
tab.BindClickEvent(TabOnClick, childID);
|
||||
_tabDic[childID] = tab;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SwitchPage(initChildID);
|
||||
return tab;
|
||||
}
|
||||
|
||||
public void CreatTabByItem<T>(int initChildID, GameObject go) where T : SwitchTabItem, new()
|
||||
{
|
||||
if (!_tabDic.ContainsKey(initChildID))
|
||||
{
|
||||
T tab = _owner.CreateWidgetByPrefab<T>(go, m_tabGrid);
|
||||
tab.UpdateTabName(_tabName[initChildID]);
|
||||
tab.BindClickEvent(TabOnClick, initChildID);
|
||||
_tabDic[initChildID] = tab;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置页签的自定义点击行为
|
||||
public void SetCustomTabClickAction(int tabIdx, Action<SwitchTabItem> clickAction, object param1 = null,
|
||||
object param2 = null, object param3 = null)
|
||||
{
|
||||
_tabDic[tabIdx].BindClickEvent(clickAction, param1, param2, param3);
|
||||
}
|
||||
|
||||
public int TabCount => _tabDic.Count;
|
||||
|
||||
public void SetTabRedNode(int tabId, bool isShow)
|
||||
{
|
||||
if (_tabDic.TryGetValue(tabId, out var value))
|
||||
{
|
||||
value.SetRedNote(isShow);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTabFontSize(int fontSize)
|
||||
{
|
||||
for (int i = 0; i < IDList.Count; i++)
|
||||
{
|
||||
var tabId = IDList[i];
|
||||
_tabDic[tabId].SetITabTextFontSize(fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void TabOnClick(SwitchTabItem tab)
|
||||
{
|
||||
var childID = (int)tab.EventParam1;
|
||||
SwitchPage(childID);
|
||||
}
|
||||
|
||||
public virtual void SwitchPage(int selectID)
|
||||
{
|
||||
if (_switchTabCondition != null && !_switchTabCondition(selectID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentChildID != selectID)
|
||||
{
|
||||
if (_switchPageDic.TryGetValue(selectID, out var pageLs))
|
||||
{
|
||||
for (int i = 0; i < pageLs.Count; i++)
|
||||
{
|
||||
var pageName = pageLs[i];
|
||||
ChildPageBase page = GetChildPageByName(pageName);
|
||||
if (page != null && page.gameObject == null)
|
||||
{
|
||||
page.CreateByPath(pageName, _owner, ChildPageParent);
|
||||
page.InitData(_shareData);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _childPageNames.Count; i++)
|
||||
{
|
||||
string pageName = _childPageNames[i];
|
||||
ChildPageBase page = GetChildPageByName(pageName);
|
||||
bool beShow = pageLs.IndexOf(pageName) >= 0;
|
||||
if (page != null && page.gameObject != null)
|
||||
{
|
||||
if (_needSetActive)
|
||||
{
|
||||
//page.Show(beShow);
|
||||
if (beShow)
|
||||
{
|
||||
page.gameObject.SetActive(true);
|
||||
// page.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
page.gameObject.SetActive(false);
|
||||
// page.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (page != null && beShow)
|
||||
if (page != null)
|
||||
{
|
||||
page.OnPageShowed(CurrentChildID, selectID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var index = 0; index < IDList.Count; index++)
|
||||
{
|
||||
var childID = IDList[index];
|
||||
SwitchTabItem tab;
|
||||
if (_tabDic.TryGetValue(childID, out tab))
|
||||
{
|
||||
tab.SetState(selectID == childID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var oldID = CurrentChildID;
|
||||
CurrentChildID = selectID;
|
||||
if (SwitchTabAction != null)
|
||||
{
|
||||
SwitchTabAction(oldID, selectID);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ShowPage(int selectID)
|
||||
{
|
||||
if (_switchPageDic.TryGetValue(selectID, out var pageLs))
|
||||
{
|
||||
for (int i = 0; i < pageLs.Count; i++)
|
||||
{
|
||||
var pageName = pageLs[i];
|
||||
ChildPageBase page = GetChildPageByName(pageName);
|
||||
if (page != null && page.gameObject == null)
|
||||
{
|
||||
page.CreateByPath(pageName, _owner, ChildPageParent);
|
||||
page.InitData(_shareData);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _childPageNames.Count; i++)
|
||||
{
|
||||
string pageName = _childPageNames[i];
|
||||
ChildPageBase page = GetChildPageByName(pageName);
|
||||
bool beShow = pageLs.IndexOf(pageName) >= 0;
|
||||
if (page != null && page.gameObject != null)
|
||||
{
|
||||
if (beShow)
|
||||
{
|
||||
page.gameObject.SetActive(true);
|
||||
// page.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
page.gameObject.SetActive(false);
|
||||
// page.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var index = 0; index < IDList.Count; index++)
|
||||
{
|
||||
var childID = IDList[index];
|
||||
SwitchTabItem tab;
|
||||
if (_tabDic.TryGetValue(childID, out tab))
|
||||
{
|
||||
tab.SetState(selectID == childID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshCurrentChildPage()
|
||||
{
|
||||
if (_switchPageDic.TryGetValue(CurrentChildID, out var pageNames))
|
||||
{
|
||||
for (int i = 0; i < pageNames.Count; i++)
|
||||
{
|
||||
ChildPageBase page = GetChildPageByName(pageNames[i]);
|
||||
if (page != null && page.gameObject != null)
|
||||
{
|
||||
page.RefreshPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshChildPage(int childID)
|
||||
{
|
||||
if (_switchPageDic.TryGetValue(childID, out var pageNames))
|
||||
{
|
||||
for (int i = 0; i < pageNames.Count; i++)
|
||||
{
|
||||
ChildPageBase page = GetChildPageByName(pageNames[i]);
|
||||
if (page != null && page.gameObject != null)
|
||||
{
|
||||
page.RefreshPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetChildPage<T>(out T t) where T : ChildPageBase
|
||||
{
|
||||
t = GetChildPage<T>();
|
||||
return t != null;
|
||||
}
|
||||
|
||||
public int GetCurShowType()
|
||||
{
|
||||
return CurrentChildID;
|
||||
}
|
||||
|
||||
public void ReductionShowType()
|
||||
{
|
||||
CurrentChildID = -100;
|
||||
}
|
||||
|
||||
#region 没有ChildPage,可通过m_switchTabAction来处理切页事件(也可以光展示用)
|
||||
|
||||
public SwitchTabItem GetTabItem(int childId)
|
||||
{
|
||||
_tabDic.TryGetValue(childId, out var item);
|
||||
return item;
|
||||
}
|
||||
|
||||
public void CreateJumpTab<T>(int initChildID, string tabName, GameObject tabTemp = null)
|
||||
where T : SwitchTabItem, new()
|
||||
{
|
||||
if (IDList.IndexOf(initChildID) < 0)
|
||||
{
|
||||
IDList.Add(initChildID);
|
||||
}
|
||||
|
||||
_tabName[initChildID] = tabName;
|
||||
|
||||
for (var index = 0; index < IDList.Count; index++)
|
||||
{
|
||||
var childID = IDList[index];
|
||||
if (!_tabDic.ContainsKey(childID))
|
||||
{
|
||||
T tab;
|
||||
if (tabTemp != null)
|
||||
{
|
||||
tab = _owner.CreateWidgetByPrefab<T>(tabTemp, m_tabGrid);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab = _owner.CreateWidgetByType<T>(m_tabGrid);
|
||||
}
|
||||
|
||||
tab.UpdateTabName(_tabName[childID]);
|
||||
tab.BindClickEvent(TabOnClick, childID);
|
||||
_tabDic[childID] = tab;
|
||||
}
|
||||
}
|
||||
|
||||
SwitchPage(initChildID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 设置共享参数。
|
||||
/// </summary>
|
||||
/// <param name="paramIdx"></param>
|
||||
/// <param name="param"></param>
|
||||
public void SetShareParam(int paramIdx, object param)
|
||||
{
|
||||
_shareData.SetParam(paramIdx, param);
|
||||
}
|
||||
|
||||
public T GetChildPage<T>() where T : ChildPageBase
|
||||
{
|
||||
var pageName = typeof(T).Name;
|
||||
_childPageDic.TryGetValue(pageName, out var page);
|
||||
return page as T;
|
||||
}
|
||||
|
||||
public ChildPageBase GetChildPageByName(string pageName)
|
||||
{
|
||||
_childPageDic.TryGetValue(pageName, out var page);
|
||||
return page;
|
||||
}
|
||||
|
||||
public void BindChildPage<T, U>(int childID, string tabName)
|
||||
where T : ChildPageBase, new()
|
||||
where U : ChildPageBase, new()
|
||||
{
|
||||
BindChildPage<T>(childID, tabName);
|
||||
BindChildPage<U>(childID, tabName);
|
||||
}
|
||||
|
||||
public void BindChildPage<T, U, V>(int childID, string tabName)
|
||||
where T : ChildPageBase, new()
|
||||
where U : ChildPageBase, new()
|
||||
where V : ChildPageBase, new()
|
||||
{
|
||||
BindChildPage<T>(childID, tabName);
|
||||
BindChildPage<U>(childID, tabName);
|
||||
BindChildPage<V>(childID, tabName);
|
||||
}
|
||||
|
||||
public void BindChildPage<T, U, V, W>(int childID, string tabName)
|
||||
where T : ChildPageBase, new()
|
||||
where U : ChildPageBase, new()
|
||||
where V : ChildPageBase, new()
|
||||
where W : ChildPageBase, new()
|
||||
{
|
||||
BindChildPage<T>(childID, tabName);
|
||||
BindChildPage<U>(childID, tabName);
|
||||
BindChildPage<V>(childID, tabName);
|
||||
BindChildPage<W>(childID, tabName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e04155ae1ce3448587a5e322477d0076
|
||||
timeCreated: 1687859725
|
@@ -1,263 +0,0 @@
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class SwitchTabItem : UIEventItem<SwitchTabItem>
|
||||
{
|
||||
//选中时的文本
|
||||
protected TextMeshProUGUI m_selectText;
|
||||
//未选中时的文本
|
||||
protected TextMeshProUGUI m_noSelectText;
|
||||
//选中时的图片
|
||||
protected Image m_selectImage;
|
||||
//未选中时的图片
|
||||
protected Image m_noSelectImage;
|
||||
//选中时的节点
|
||||
protected Transform m_selectNode;
|
||||
//未选中时的节点
|
||||
protected Transform m_noSelectNode;
|
||||
|
||||
//选中时的Icon
|
||||
protected Image m_selectIcon;
|
||||
//未选中时的Icon
|
||||
protected Image m_noSelectIcon;
|
||||
|
||||
protected GameObject m_goRedNote;
|
||||
|
||||
//是否选中
|
||||
public bool IsSelect
|
||||
{
|
||||
get { return m_isSelect; }
|
||||
set { SetState(value); }
|
||||
}
|
||||
|
||||
protected bool m_isSelect = false;
|
||||
|
||||
//private RedNoteBehaviour m_redNote;
|
||||
public RedNoteWidget m_redNote { get; private set; }
|
||||
|
||||
public virtual Vector2 SelectRedPointPos
|
||||
{
|
||||
get
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector2 NoSelectRedPointPos
|
||||
{
|
||||
get
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public override void BindMemberProperty()
|
||||
{
|
||||
m_selectNode = FindChild("SelectNode");
|
||||
m_noSelectNode = FindChild("NoSelectNode");
|
||||
if (m_selectNode != null)
|
||||
{
|
||||
m_selectText = FindChildComponent<TextMeshProUGUI>(m_selectNode, "SelectText");
|
||||
m_selectImage = FindChildComponent<Image>(m_selectNode, "SelectImage");
|
||||
m_selectIcon = FindChildComponent<Image>(m_selectNode, "SelectIcon");
|
||||
}
|
||||
if (m_noSelectNode != null)
|
||||
{
|
||||
m_noSelectText = FindChildComponent<TextMeshProUGUI>(m_noSelectNode, "NoSelectText");
|
||||
m_noSelectImage = FindChildComponent<Image>(m_noSelectNode, "NoSelectImage");
|
||||
m_noSelectIcon = FindChildComponent<Image>(m_noSelectNode, "NoSelectIcon");
|
||||
}
|
||||
|
||||
var tf = FindChild("m_goRedNote");
|
||||
if (tf != null)
|
||||
{
|
||||
m_goRedNote = tf.gameObject;
|
||||
m_redNote = CreateWidgetByType<RedNoteWidget>(tf);
|
||||
m_redNote.rectTransform.anchoredPosition = Vector2.zero;
|
||||
SetRedNote(false);
|
||||
//CreateDefaultRedNote();
|
||||
}
|
||||
}
|
||||
|
||||
#region 红点相关
|
||||
public void SetRedNoteType(RedNoteNotify type)
|
||||
{
|
||||
if (m_redNote != null)
|
||||
{
|
||||
m_redNote.m_redNote.SetNotifyType(type);
|
||||
}
|
||||
SetRedNote(true);
|
||||
}
|
||||
|
||||
public void SetRedNoteType(RedNoteNotify type, ulong param1)
|
||||
{
|
||||
if (m_redNote != null)
|
||||
{
|
||||
m_redNote.m_redNote.SetNotifyType(type, param1);
|
||||
}
|
||||
SetRedNote(true);
|
||||
}
|
||||
|
||||
public void SetRedNoteType(RedNoteNotify type, ulong param1, ulong param2)
|
||||
{
|
||||
if (m_redNote != null)
|
||||
{
|
||||
m_redNote.m_redNote.SetNotifyType(type, param1, param2);
|
||||
}
|
||||
SetRedNote(true);
|
||||
}
|
||||
|
||||
public void SetRedNoteType(RedNoteNotify type, ulong param1, ulong param2, ulong param3)
|
||||
{
|
||||
if (m_redNote != null)
|
||||
{
|
||||
m_redNote.m_redNote.SetNotifyType(type, param1, param2, param3);
|
||||
}
|
||||
SetRedNote(true);
|
||||
}
|
||||
|
||||
public void SetRedNoteState(bool state)
|
||||
{
|
||||
if (m_redNote != null)
|
||||
{
|
||||
m_redNote.m_redNote.SetRedNoteState(state);
|
||||
}
|
||||
SetRedNote(state);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void UpdateTabName(string tabName)
|
||||
{
|
||||
if (m_selectText != null)
|
||||
{
|
||||
m_selectText.text = tabName;
|
||||
m_selectText.rectTransform.sizeDelta = new Vector2(m_selectText.preferredWidth, m_selectText.rectTransform.sizeDelta.y);
|
||||
}
|
||||
if (m_noSelectText != null)
|
||||
{
|
||||
m_noSelectText.text = tabName;
|
||||
m_noSelectText.rectTransform.sizeDelta = new Vector2(m_noSelectText.preferredWidth, m_noSelectText
|
||||
.rectTransform.sizeDelta.y);
|
||||
}
|
||||
}
|
||||
|
||||
// public void UpdateTabImage(string selectImageName,string noSelectImageName)
|
||||
// {
|
||||
// if (m_selectImage != null)
|
||||
// {
|
||||
// UISpriteHelper.Instance.SetSprite(m_selectImage, selectImageName);
|
||||
// }
|
||||
// if (m_noSelectImage != null)
|
||||
// {
|
||||
// UISpriteHelper.Instance.SetSprite(m_noSelectImage, noSelectImageName);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void UpdateIcon(string selectIconName, string noSelectIconName)
|
||||
// {
|
||||
// if (m_selectIcon != null)
|
||||
// {
|
||||
// DUISpriteHelper.Instance.SetSprite(m_selectIcon, selectIconName, true);
|
||||
// }
|
||||
// if (m_noSelectIcon != null)
|
||||
// {
|
||||
// DUISpriteHelper.Instance.SetSprite(m_noSelectIcon, noSelectIconName, true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public virtual void CreateDefaultRedNote()
|
||||
// {
|
||||
// if (m_goRedNote != null)
|
||||
// {
|
||||
// UIEffectHelper.CreateUIEffectGoById((uint)CommonEffectID.EffectRedPoint, m_goRedNote.transform);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void SetRedNote(bool show)
|
||||
{
|
||||
if (m_goRedNote != null)
|
||||
{
|
||||
m_goRedNote.SetActive(show);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetState(bool select)
|
||||
{
|
||||
m_isSelect = select;
|
||||
if (m_selectNode != null)
|
||||
{
|
||||
m_selectNode.gameObject.SetActive(select);
|
||||
}
|
||||
if (m_noSelectNode != null)
|
||||
{
|
||||
m_noSelectNode.gameObject.SetActive(!select);
|
||||
}
|
||||
|
||||
if (m_goRedNote != null)
|
||||
{
|
||||
if (select)
|
||||
{
|
||||
if (SelectRedPointPos != Vector2.zero)
|
||||
{
|
||||
((RectTransform)m_goRedNote.transform).anchoredPosition = SelectRedPointPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NoSelectRedPointPos != Vector2.zero)
|
||||
{
|
||||
((RectTransform)m_goRedNote.transform).anchoredPosition = NoSelectRedPointPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetITabTextFontSize(int fontSize)
|
||||
{
|
||||
if (m_selectText != null)
|
||||
{
|
||||
m_selectText.fontSize = fontSize;
|
||||
}
|
||||
if (m_noSelectText != null)
|
||||
{
|
||||
m_noSelectText.fontSize = fontSize;
|
||||
}
|
||||
}
|
||||
|
||||
#region UI-ID
|
||||
/// <summary>
|
||||
/// UI-ID
|
||||
/// </summary>
|
||||
public uint uiID;
|
||||
|
||||
/// <summary>
|
||||
/// UI标识
|
||||
/// </summary>
|
||||
protected string m_uiFlag;
|
||||
|
||||
/// <summary>
|
||||
/// 检查方法
|
||||
/// </summary>
|
||||
protected Func<bool> m_funcCheck;
|
||||
|
||||
/// <summary>
|
||||
/// 页签索引
|
||||
/// </summary>
|
||||
public int tabIndex = -1;
|
||||
|
||||
/// <summary>
|
||||
/// UI标识
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetUiFlag()
|
||||
{
|
||||
return string.IsNullOrEmpty(m_uiFlag) ? uiID.ToString() : m_uiFlag;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 498417b8785d47249da952f77d069c33
|
||||
timeCreated: 1687667780
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b50cf85b0f0d4e43b12cb694f6c07979
|
||||
timeCreated: 1695289335
|
@@ -1,18 +0,0 @@
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class EmptyGraph : Graphic
|
||||
{
|
||||
public bool m_debug = false;
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vbo)
|
||||
{
|
||||
vbo.Clear();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_debug)
|
||||
{
|
||||
base.OnPopulateMesh(vbo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21df3dfa358b498e8da3d169d736df58
|
||||
timeCreated: 1695289370
|
@@ -1,138 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
[AddComponentMenu("UI/TScrollRect Rect", 37)]
|
||||
[SelectionBase]
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof (RectTransform))]
|
||||
public class TScrollRect : ScrollRect
|
||||
{
|
||||
private event Action ActionBeginDrag;
|
||||
private event Action ActionOnDrag;
|
||||
private event Action ActionEndDrag;
|
||||
|
||||
public List<ScrollRect> parentScrollRectList;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
if (parentScrollRectList != null && parentScrollRectList.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < parentScrollRectList.Count; i++)
|
||||
{
|
||||
AddParentScrollRect(parentScrollRectList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ScrollRect> m_listParentScrollRect;
|
||||
|
||||
public void AddParentScrollRect(ScrollRect parentScrollRect)
|
||||
{
|
||||
if (parentScrollRect == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_listParentScrollRect == null)
|
||||
{
|
||||
m_listParentScrollRect = new List<ScrollRect>();
|
||||
}
|
||||
|
||||
if (!m_listParentScrollRect.Contains(parentScrollRect))
|
||||
{
|
||||
m_listParentScrollRect.Add(parentScrollRect);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddBeginDragListener(Action action)
|
||||
{
|
||||
ActionBeginDrag += action;
|
||||
}
|
||||
|
||||
public void RemoveBeginDragListener(Action action)
|
||||
{
|
||||
ActionBeginDrag -= action;
|
||||
}
|
||||
|
||||
public void AddOnDragListener(Action action)
|
||||
{
|
||||
ActionOnDrag += action;
|
||||
}
|
||||
|
||||
public void RemoveOnDragListener(Action action)
|
||||
{
|
||||
ActionOnDrag -= action;
|
||||
}
|
||||
|
||||
public void AddEndDragListener(Action action)
|
||||
{
|
||||
ActionEndDrag += action;
|
||||
}
|
||||
|
||||
public void RemoveEndDragListener(Action action)
|
||||
{
|
||||
ActionEndDrag -= action;
|
||||
}
|
||||
|
||||
public override void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
base.OnBeginDrag(eventData);
|
||||
if (ActionBeginDrag != null)
|
||||
{
|
||||
ActionBeginDrag();
|
||||
}
|
||||
|
||||
if (m_listParentScrollRect != null)
|
||||
{
|
||||
for (int i = 0; i < m_listParentScrollRect.Count; i++)
|
||||
{
|
||||
var parentScrollRect = m_listParentScrollRect[i];
|
||||
parentScrollRect.OnBeginDrag(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
base.OnDrag(eventData);
|
||||
if (ActionOnDrag != null)
|
||||
{
|
||||
ActionOnDrag();
|
||||
}
|
||||
|
||||
if (m_listParentScrollRect != null)
|
||||
{
|
||||
for (int i = 0; i < m_listParentScrollRect.Count; i++)
|
||||
{
|
||||
var parentScrollRect = m_listParentScrollRect[i];
|
||||
parentScrollRect.OnDrag(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
base.OnEndDrag(eventData);
|
||||
if (ActionEndDrag != null)
|
||||
{
|
||||
ActionEndDrag();
|
||||
}
|
||||
|
||||
if (m_listParentScrollRect != null)
|
||||
{
|
||||
for (int i = 0; i < m_listParentScrollRect.Count; i++)
|
||||
{
|
||||
var parentScrollRect = m_listParentScrollRect[i];
|
||||
parentScrollRect.OnEndDrag(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d322e77e03014f65a9ec277d50bd12f8
|
||||
timeCreated: 1695289370
|
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UIButtonSound : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
private static Action<int> _playSoundAction = null;
|
||||
|
||||
public int clickSound = 2;
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (_playSoundAction != null)
|
||||
{
|
||||
_playSoundAction(clickSound);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddPlaySoundAction(Action<int> onClick)
|
||||
{
|
||||
_playSoundAction += onClick;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb272eb1eec94625884e6e83889daa9a
|
||||
timeCreated: 1695289370
|
@@ -1,226 +0,0 @@
|
||||
using System;
|
||||
using TEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UIEventItem<T> : UIWidget where T : UIEventItem<T>
|
||||
{
|
||||
private object m_eventParam1;
|
||||
private object m_eventParam2;
|
||||
private object m_eventParam3;
|
||||
public object EventParam1 => m_eventParam1;
|
||||
|
||||
public object EventParam2 => m_eventParam2;
|
||||
|
||||
public object EventParam3 => m_eventParam3;
|
||||
private Action<T> m_clickAction;
|
||||
private Action<T, bool> m_pressAction;
|
||||
private Action<T, PointerEventData> m_beginDragAction;
|
||||
private Action<T, PointerEventData> m_dragAction;
|
||||
private Action<T, PointerEventData> m_endDragAction;
|
||||
|
||||
public void BindClickEvent(Action<T> clickAction, object eParam1 = null, object eParam2 = null, object eParam3 = null,
|
||||
Selectable.Transition transition = Selectable.Transition.ColorTint)
|
||||
{
|
||||
if (m_clickAction != null)
|
||||
{
|
||||
m_clickAction = clickAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clickAction = clickAction;
|
||||
var button = gameObject.GetOrAddComponent<Button>();
|
||||
button.transition = transition;
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
if (m_clickAction != null)
|
||||
{
|
||||
m_clickAction(this as T);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindClickEventEx(Action<T> clickAction, object eParam1 = null, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
if (m_clickAction != null)
|
||||
{
|
||||
m_clickAction = clickAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clickAction = clickAction;
|
||||
var button = gameObject.GetOrAddComponent<Button>();
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
if (m_clickAction != null)
|
||||
{
|
||||
m_clickAction(this as T);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindBeginDragEvent(Action<T, PointerEventData> dragAction, object eParam1 = null, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
if (m_beginDragAction != null)
|
||||
{
|
||||
m_beginDragAction = dragAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_beginDragAction = dragAction;
|
||||
var trigger = gameObject.GetOrAddComponent<EventTrigger>();
|
||||
EventTrigger.Entry entry = new EventTrigger.Entry();
|
||||
entry.eventID = EventTriggerType.BeginDrag;
|
||||
entry.callback = new EventTrigger.TriggerEvent();
|
||||
entry.callback.AddListener((data) =>
|
||||
{
|
||||
var pointerEventData = (PointerEventData)data;
|
||||
if (m_beginDragAction != null)
|
||||
{
|
||||
m_beginDragAction(this as T, pointerEventData);
|
||||
}
|
||||
});
|
||||
trigger.triggers.Add(entry);
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindDragEvent(Action<T, PointerEventData> dragAction, object eParam1 = null, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
if (m_dragAction != null)
|
||||
{
|
||||
m_dragAction = dragAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dragAction = dragAction;
|
||||
var trigger = gameObject.GetOrAddComponent<EventTrigger>();
|
||||
EventTrigger.Entry entry = new EventTrigger.Entry();
|
||||
entry.eventID = EventTriggerType.Drag;
|
||||
entry.callback = new EventTrigger.TriggerEvent();
|
||||
entry.callback.AddListener((data) =>
|
||||
{
|
||||
var pointerEventData = (PointerEventData)data;
|
||||
if (m_dragAction != null)
|
||||
{
|
||||
m_dragAction(this as T, pointerEventData);
|
||||
}
|
||||
});
|
||||
trigger.triggers.Add(entry);
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindEndDragEvent(Action<T, PointerEventData> dragendAction, object eParam1 = null, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
if (m_endDragAction != null)
|
||||
{
|
||||
m_endDragAction = dragendAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_endDragAction = dragendAction;
|
||||
var trigger = gameObject.GetOrAddComponent<EventTrigger>();
|
||||
EventTrigger.Entry entry = new EventTrigger.Entry();
|
||||
entry.eventID = EventTriggerType.EndDrag;
|
||||
entry.callback = new EventTrigger.TriggerEvent();
|
||||
entry.callback.AddListener((data) =>
|
||||
{
|
||||
if (m_endDragAction != null)
|
||||
{
|
||||
m_endDragAction(this as T, (PointerEventData)data);
|
||||
}
|
||||
});
|
||||
trigger.triggers.Add(entry);
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindPressEvent(Action<T, bool> pressAction, object eParam1 = null, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
if (m_pressAction != null)
|
||||
{
|
||||
m_pressAction = pressAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pressAction = pressAction;
|
||||
var trigger = gameObject.GetOrAddComponent<EventTrigger>();
|
||||
EventTrigger.Entry entry = new EventTrigger.Entry();
|
||||
entry.eventID = EventTriggerType.PointerDown;
|
||||
entry.callback = new EventTrigger.TriggerEvent();
|
||||
entry.callback.AddListener((data) =>
|
||||
{
|
||||
if (m_pressAction != null)
|
||||
{
|
||||
m_pressAction(this as T, true);
|
||||
}
|
||||
});
|
||||
trigger.triggers.Add(entry);
|
||||
entry = new EventTrigger.Entry();
|
||||
entry.eventID = EventTriggerType.PointerUp;
|
||||
entry.callback = new EventTrigger.TriggerEvent();
|
||||
entry.callback.AddListener((data) =>
|
||||
{
|
||||
if (m_pressAction != null)
|
||||
{
|
||||
m_pressAction(this as T, false);
|
||||
}
|
||||
});
|
||||
trigger.triggers.Add(entry);
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void BindPressEventEx(Action<T, bool> pressAction, object eParam1 = null, object eParam2 = null, object eParam3 = null,
|
||||
float durationThreshold = 1)
|
||||
{
|
||||
if (m_pressAction != null)
|
||||
{
|
||||
m_pressAction = pressAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pressAction = pressAction;
|
||||
var button = gameObject.GetOrAddComponent<UIButtonSuper>();
|
||||
button.m_LongPressDurationTime = durationThreshold;
|
||||
button.onPress.AddListener(() =>
|
||||
{
|
||||
if (m_pressAction != null)
|
||||
{
|
||||
m_pressAction(this as T, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SetEventParam(eParam1, eParam2, eParam3);
|
||||
}
|
||||
|
||||
public void SetEventParam(object eParam1, object eParam2 = null, object eParam3 = null)
|
||||
{
|
||||
m_eventParam1 = eParam1;
|
||||
m_eventParam2 = eParam2;
|
||||
m_eventParam3 = eParam3;
|
||||
}
|
||||
|
||||
public void OnTriggerBtnEvent()
|
||||
{
|
||||
if (m_clickAction != null)
|
||||
{
|
||||
m_clickAction(this as T);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9972ff1d1514807bbd21d6bc4c035f4
|
||||
timeCreated: 1695289504
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d3f2e9ab868464da947f3d52aa9c3f6
|
||||
timeCreated: 1695289443
|
@@ -1,349 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// UI列表Item
|
||||
/// </summary>
|
||||
/// <typeparam name="TData"></typeparam>
|
||||
public interface IListDataItem<in TData>
|
||||
{
|
||||
void SetItemData(TData d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI列表Item
|
||||
/// </summary>
|
||||
public interface IListSelectItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取索引。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int GetItemIndex();
|
||||
|
||||
/// <summary>
|
||||
/// 设置索引。
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
void SetItemIndex(int i);
|
||||
|
||||
/// <summary>
|
||||
/// 是否被选中。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool IsSelected();
|
||||
|
||||
/// <summary>
|
||||
/// 设置是否选中。
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
void SetSelected(bool v);
|
||||
}
|
||||
|
||||
public class SelectItemBase : UIEventItem<SelectItemBase>, IListSelectItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引。
|
||||
/// </summary>
|
||||
protected int m_itemIndex;
|
||||
|
||||
public int GetItemIndex()
|
||||
{
|
||||
return m_itemIndex;
|
||||
}
|
||||
|
||||
public void SetItemIndex(int i)
|
||||
{
|
||||
m_itemIndex = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否被选中。
|
||||
/// </summary>
|
||||
protected bool m_isSelected;
|
||||
|
||||
public virtual bool IsSelected()
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
public virtual void SetSelected(bool v)
|
||||
{
|
||||
if (m_isSelected == v) return;
|
||||
m_isSelected = v;
|
||||
UpdateSelect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新选中状态。
|
||||
/// </summary>
|
||||
public virtual void UpdateSelect()
|
||||
{
|
||||
}
|
||||
|
||||
public override void RegisterEvent()
|
||||
{
|
||||
base.RegisterEvent();
|
||||
AddSelectEvt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 监听选中事件。
|
||||
/// </summary>
|
||||
protected virtual void AddSelectEvt()
|
||||
{
|
||||
if (Parent == null || !(Parent is IUISelectList)) return;
|
||||
var btn = gameObject.GetOrAddComponent<Button>();
|
||||
if (btn != null)
|
||||
{
|
||||
btn.onClick.AddListener(OnSelectClick);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中点击
|
||||
/// </summary>
|
||||
protected virtual void OnSelectClick()
|
||||
{
|
||||
var p = Parent as IUISelectList;
|
||||
if (p != null)
|
||||
{
|
||||
p.OnItemClick(this, GetItemIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IUISelectList
|
||||
{
|
||||
void OnItemClick(object item, int i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI列表
|
||||
/// </summary>
|
||||
public class UIListBase<ItemT, DataT> : UIWidget, IUISelectList where ItemT : UIWidget, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// item模板
|
||||
/// </summary>
|
||||
public GameObject itemBase;
|
||||
|
||||
/// <summary>
|
||||
/// 数据列表
|
||||
/// </summary>
|
||||
protected List<DataT> m_datas;
|
||||
|
||||
/// <summary>
|
||||
/// 数据列表
|
||||
/// </summary>
|
||||
public List<DataT> datas => m_datas;
|
||||
|
||||
/// <summary>
|
||||
/// 数据数量
|
||||
/// </summary>
|
||||
public int DataNum => m_datas?.Count ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// 数量
|
||||
/// </summary>
|
||||
protected int m_num;
|
||||
|
||||
/// <summary>
|
||||
/// 数量
|
||||
/// </summary>
|
||||
public int num => m_num;
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据数量
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="funcItem"></param>
|
||||
public void SetDataNum(int n, Action<ItemT, int> funcItem = null)
|
||||
{
|
||||
AdjustItemNum(n, null, funcItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据起始索引
|
||||
/// </summary>
|
||||
public int dataStartOffset = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据
|
||||
/// </summary>
|
||||
/// <param name="dataList"></param>
|
||||
/// <param name="n"></param>
|
||||
public void SetDatas(List<DataT> dataList, int n = -1)
|
||||
{
|
||||
AdjustItemNum(Mathf.Max(0, n >= 0 ? n : (dataList == null ? 0 : (dataList.Count - dataStartOffset))), dataList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置显示数据
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="datas"></param>
|
||||
/// <param name="funcItem"></param>
|
||||
protected virtual void AdjustItemNum(int n, List<DataT> datas = null, Action<ItemT, int> funcItem = null)
|
||||
{
|
||||
m_num = n;
|
||||
m_datas = datas;
|
||||
if (itemBase != null)
|
||||
{
|
||||
itemBase.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新列表ITEM
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="i"></param>
|
||||
/// <param name="func"></param>
|
||||
protected virtual void UpdateListItem(ItemT item, int i, Action<ItemT, int> func)
|
||||
{
|
||||
if (item == null) return;
|
||||
if (func != null)
|
||||
{
|
||||
func.Invoke(item, i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item is IListDataItem<DataT> listDataItem)
|
||||
{
|
||||
listDataItem.SetItemData(GetData(i));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中索引
|
||||
/// </summary>
|
||||
protected int m_selectIndex = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Item点击
|
||||
/// </summary>
|
||||
public Action<int> funcOnItemClick;
|
||||
|
||||
/// <summary>
|
||||
/// 选中变化回调函数
|
||||
/// </summary>
|
||||
public Action funcOnSelectChange;
|
||||
|
||||
/// <summary>
|
||||
/// 点击无选中变化回调
|
||||
/// </summary>
|
||||
public Action funcNoSelectChange;
|
||||
|
||||
/// <summary>
|
||||
/// 选中索引
|
||||
/// </summary>
|
||||
public int selectIndex
|
||||
{
|
||||
get => m_selectIndex;
|
||||
set => SetSelectIndex(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置选中索引
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <param name="forceUpdate"></param>
|
||||
/// <param name="triggerEvt"></param>
|
||||
public void SetSelectIndex(int i, bool forceUpdate = false, bool triggerEvt = true)
|
||||
{
|
||||
if (!forceUpdate && m_selectIndex == i)
|
||||
{
|
||||
if (funcNoSelectChange != null)
|
||||
{
|
||||
funcNoSelectChange.Invoke();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var preIndex = selectIndex;
|
||||
m_selectIndex = i;
|
||||
if (GetItem(preIndex) is IListSelectItem item)
|
||||
{
|
||||
item.SetSelected(false);
|
||||
}
|
||||
|
||||
item = GetItem(selectIndex) as IListSelectItem;
|
||||
if (item != null)
|
||||
{
|
||||
item.SetSelected(true);
|
||||
}
|
||||
UpdateSnapTargetItem();
|
||||
if (triggerEvt && funcOnSelectChange != null)
|
||||
{
|
||||
funcOnSelectChange.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新Snap
|
||||
/// </summary>
|
||||
protected virtual void UpdateSnapTargetItem()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前选中的数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DataT GetSelectData()
|
||||
{
|
||||
return GetData(selectIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <returns></returns>
|
||||
public DataT GetData(int i)
|
||||
{
|
||||
i += dataStartOffset;
|
||||
return m_datas == null || i < 0 || i >= m_datas.Count ? default(DataT) : m_datas[i];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取item
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <returns></returns>
|
||||
public virtual ItemT GetItem(int i)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击选择
|
||||
/// </summary>
|
||||
public bool SelectByClick = true;
|
||||
|
||||
/// <summary>
|
||||
/// item被点击
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="i"></param>
|
||||
public void OnItemClick(object item, int i)
|
||||
{
|
||||
if (funcOnItemClick != null)
|
||||
{
|
||||
funcOnItemClick.Invoke(i);
|
||||
}
|
||||
|
||||
if (SelectByClick)
|
||||
{
|
||||
selectIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d3742a744bb4934a4848b54bb6910a2
|
||||
timeCreated: 1691679426
|
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 普通UI列表。
|
||||
/// </summary>
|
||||
public class UIListWidget<TItem, TData> : UIListBase<TItem, TData> where TItem : UIWidget, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// item列表。
|
||||
/// </summary>
|
||||
protected List<TItem> m_items = new List<TItem>();
|
||||
|
||||
/// <summary>
|
||||
/// item列表。
|
||||
/// </summary>
|
||||
public List<TItem> items => m_items;
|
||||
|
||||
/// <summary>
|
||||
/// 设置显示数据。
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="datas"></param>
|
||||
/// <param name="funcItem"></param>
|
||||
protected override void AdjustItemNum(int n, List<TData> datas = null, Action<TItem, int> funcItem = null)
|
||||
{
|
||||
base.AdjustItemNum(n, datas, funcItem);
|
||||
AdjustIconNum(m_items, n, gameObject.transform, itemBase);
|
||||
UpdateList(funcItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新列表。
|
||||
/// </summary>
|
||||
/// <param name="funcItem"></param>
|
||||
protected void UpdateList(Action<TItem, int> funcItem = null)
|
||||
{
|
||||
for (var i = 0; i < m_items.Count; i++)
|
||||
{
|
||||
UpdateListItem(m_items[i], i, funcItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取item
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <returns></returns>
|
||||
public override TItem GetItem(int i)
|
||||
{
|
||||
return i >= 0 && i < m_items.Count ? m_items[i] : null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96f732d895e94fbc99c904d66ca844ca
|
||||
timeCreated: 1701844130
|
@@ -1,14 +0,0 @@
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UILoopGridItemWidget: SelectItemBase
|
||||
{
|
||||
public LoopGridViewItem LoopItem { set; get; }
|
||||
|
||||
public int Index { private set; get; }
|
||||
|
||||
public virtual void UpdateItem(int index)
|
||||
{
|
||||
Index = index;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47ee457a0d7549b3a3b5d23f4ac048cd
|
||||
timeCreated: 1692346002
|
@@ -1,208 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// UI列表。
|
||||
/// </summary>
|
||||
public class UILoopGridWidget<TItem, TData> : UIListBase<TItem, TData> where TItem : UILoopGridItemWidget, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// LoopRectView
|
||||
/// </summary>
|
||||
public LoopGridView LoopRectView { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Item字典
|
||||
/// </summary>
|
||||
private GameFrameworkDictionary<int, TItem> m_itemCache = new GameFrameworkDictionary<int, TItem>();
|
||||
|
||||
/// <summary>
|
||||
/// 计算偏差后的ItemList
|
||||
/// </summary>
|
||||
private List<TItem> m_items = new List<TItem>();
|
||||
|
||||
/// <summary>
|
||||
/// 计算偏差后的ItemList
|
||||
/// </summary>
|
||||
public List<TItem> items => m_items;
|
||||
|
||||
public override void BindMemberProperty()
|
||||
{
|
||||
base.BindMemberProperty();
|
||||
LoopRectView = rectTransform.GetComponent<LoopGridView>();
|
||||
}
|
||||
|
||||
public override void OnCreate()
|
||||
{
|
||||
base.OnCreate();
|
||||
LoopRectView.InitGridView(0, OnGetItemByIndex);
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
m_itemCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Item回调函数
|
||||
/// </summary>
|
||||
protected Action<TItem, int> m_tpFuncItem;
|
||||
|
||||
/// <summary>
|
||||
/// 设置显示数据
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="datas"></param>
|
||||
/// <param name="funcItem"></param>
|
||||
protected override void AdjustItemNum(int n, List<TData> datas = null, Action<TItem, int> funcItem = null)
|
||||
{
|
||||
base.AdjustItemNum(n, datas, funcItem);
|
||||
m_tpFuncItem = funcItem;
|
||||
LoopRectView.SetListItemCount(n);
|
||||
LoopRectView.RefreshAllShownItem();
|
||||
m_tpFuncItem = null;
|
||||
UpdateAllItemSelect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Item
|
||||
/// </summary>
|
||||
/// <param name="listView"></param>
|
||||
/// <param name="itemIndex"></param>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="column"></param>
|
||||
/// <returns></returns>
|
||||
protected LoopGridViewItem OnGetItemByIndex(LoopGridView listView, int itemIndex,int row,int column)
|
||||
{
|
||||
if (itemIndex < 0 || itemIndex >= num) return null;
|
||||
var item = itemBase == null ? CreateItem() : CreateItem(itemBase);
|
||||
if (item == null) return null;
|
||||
item.SetItemIndex(itemIndex);
|
||||
UpdateListItem(item, itemIndex, m_tpFuncItem);
|
||||
return item.LoopItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem()
|
||||
{
|
||||
return CreateItem(typeof(TItem).Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="itemName"></param>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem(string itemName)
|
||||
{
|
||||
TItem widget = null;
|
||||
LoopGridViewItem item = LoopRectView.AllocOrNewListViewItem(itemName);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem(GameObject prefab)
|
||||
{
|
||||
TItem widget = null;
|
||||
LoopGridViewItem item = LoopRectView.AllocOrNewListViewItem(prefab);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
private TItem CreateItem(LoopGridViewItem item)
|
||||
{
|
||||
TItem widget;
|
||||
if (!m_itemCache.TryGetValue(item.GoId, out widget))
|
||||
{
|
||||
widget = CreateWidget<TItem>(item.gameObject);
|
||||
widget.LoopItem = item;
|
||||
m_itemCache.Add(item.GoId, widget);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取item
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public override TItem GetItem(int index)
|
||||
{
|
||||
for (var i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
|
||||
var item = m_itemCache.GetValueByIndex(i);
|
||||
if (item.GetItemIndex() == index)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取itemList
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<TItem> GetItemList()
|
||||
{
|
||||
m_items.Clear();
|
||||
for (int i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
m_items.Add(m_itemCache.GetValueByIndex(i));
|
||||
}
|
||||
return m_items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Item。
|
||||
/// </summary>
|
||||
/// <param name="index">索引。</param>
|
||||
/// <returns>TItem。</returns>
|
||||
public TItem GetItemByIndex(int index)
|
||||
{
|
||||
return m_itemCache.GetValueByIndex(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新所有item选中状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public void UpdateAllItemSelect()
|
||||
{
|
||||
var index = selectIndex;
|
||||
for (var i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
if (m_itemCache.GetValueByIndex(i) is IListSelectItem item)
|
||||
{
|
||||
item.SetSelected(item.GetItemIndex() == index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0930448d067145dfb0428b248f1086ae
|
||||
timeCreated: 1692346037
|
@@ -1,14 +0,0 @@
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UILoopItemWidget : SelectItemBase
|
||||
{
|
||||
public LoopListViewItem LoopItem { set; get; }
|
||||
|
||||
public int Index { private set; get; }
|
||||
|
||||
public virtual void UpdateItem(int index)
|
||||
{
|
||||
Index = index;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b39b2f052eec4a4a97256e5aeee9e7dc
|
||||
timeCreated: 1691679577
|
@@ -1,94 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
public class UILoopListViewWidget<T> : UIWidget where T : UILoopItemWidget, new()
|
||||
{
|
||||
public LoopListView LoopRectView { private set; get; }
|
||||
|
||||
private GameFrameworkDictionary<int, T> m_itemCache = new GameFrameworkDictionary<int, T>();
|
||||
|
||||
public override void BindMemberProperty()
|
||||
{
|
||||
base.BindMemberProperty();
|
||||
LoopRectView = this.rectTransform.GetComponent<LoopListView>();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
m_itemCache.Clear();
|
||||
}
|
||||
|
||||
public T CreateItem()
|
||||
{
|
||||
string typeName = typeof(T).Name;
|
||||
return CreateItem(typeName);
|
||||
;
|
||||
}
|
||||
|
||||
public T CreateItem(string itemName)
|
||||
{
|
||||
T widget = null;
|
||||
var item = LoopRectView.AllocOrNewListViewItem(itemName);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
public T CreateItem(GameObject prefab)
|
||||
{
|
||||
T widget = null;
|
||||
var item = LoopRectView.AllocOrNewListViewItem(prefab);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
private T CreateItem(LoopListViewItem item)
|
||||
{
|
||||
T widget;
|
||||
if (!m_itemCache.TryGetValue(item.GoId, out widget))
|
||||
{
|
||||
widget = CreateWidget<T>(item.gameObject);
|
||||
widget.LoopItem = item;
|
||||
m_itemCache.Add(item.GoId, widget);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
public List<T> GetItemList()
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
for (int i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
list.Add(m_itemCache.GetValueByIndex(i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public int GetItemCount()
|
||||
{
|
||||
return m_itemCache.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Item。
|
||||
/// </summary>
|
||||
/// <param name="index">索引。</param>
|
||||
/// <returns>TItem。</returns>
|
||||
public T GetItemByIndex(int index)
|
||||
{
|
||||
return m_itemCache.GetValueByIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b87126ba47740708bc82eb0bb9e414e
|
||||
timeCreated: 1691679617
|
@@ -1,225 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// UI列表。
|
||||
/// </summary>
|
||||
public class UILoopListWidget<TItem, TData> : UIListBase<TItem, TData> where TItem : UILoopItemWidget, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// LoopRectView
|
||||
/// </summary>
|
||||
public LoopListView LoopRectView { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Item字典
|
||||
/// <remarks>Key => GameObjectHashCode | Value => TItem.</remarks>
|
||||
/// </summary>
|
||||
private GameFrameworkDictionary<int, TItem> m_itemCache = new GameFrameworkDictionary<int, TItem>();
|
||||
|
||||
/// <summary>
|
||||
/// 计算偏差后的ItemList
|
||||
/// </summary>
|
||||
private List<TItem> m_items = new List<TItem>();
|
||||
|
||||
/// <summary>
|
||||
/// 计算偏差后的ItemList
|
||||
/// </summary>
|
||||
public List<TItem> items => m_items;
|
||||
|
||||
public override void BindMemberProperty()
|
||||
{
|
||||
base.BindMemberProperty();
|
||||
LoopRectView = rectTransform.GetComponent<LoopListView>();
|
||||
}
|
||||
|
||||
public override void OnCreate()
|
||||
{
|
||||
base.OnCreate();
|
||||
LoopRectView.InitListView(0, OnGetItemByIndex);
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
m_itemCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Item回调函数
|
||||
/// </summary>
|
||||
protected Action<TItem, int> m_tpFuncItem;
|
||||
|
||||
/// <summary>
|
||||
/// 设置显示数据
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="datas"></param>
|
||||
/// <param name="funcItem"></param>
|
||||
protected override void AdjustItemNum(int n, List<TData> datas = null, Action<TItem, int> funcItem = null)
|
||||
{
|
||||
base.AdjustItemNum(n, datas, funcItem);
|
||||
m_tpFuncItem = funcItem;
|
||||
LoopRectView.SetListItemCount(n);
|
||||
LoopRectView.RefreshAllShownItem();
|
||||
m_tpFuncItem = null;
|
||||
UpdateAllItemSelect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Item
|
||||
/// </summary>
|
||||
/// <param name="listView"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
protected LoopListViewItem OnGetItemByIndex(LoopListView listView, int index)
|
||||
{
|
||||
if (index < 0 || index >= num) return null;
|
||||
var item = itemBase == null ? CreateItem() : CreateItem(itemBase);
|
||||
if (item == null) return null;
|
||||
item.SetItemIndex(index);
|
||||
UpdateListItem(item, index, m_tpFuncItem);
|
||||
return item.LoopItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem()
|
||||
{
|
||||
return CreateItem(typeof(TItem).Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="itemName"></param>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem(string itemName)
|
||||
{
|
||||
TItem widget = null;
|
||||
LoopListViewItem item = LoopRectView.AllocOrNewListViewItem(itemName);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <returns></returns>
|
||||
public TItem CreateItem(GameObject prefab)
|
||||
{
|
||||
TItem widget = null;
|
||||
LoopListViewItem item = LoopRectView.AllocOrNewListViewItem(prefab);
|
||||
if (item != null)
|
||||
{
|
||||
widget = CreateItem(item);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建Item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
private TItem CreateItem(LoopListViewItem item)
|
||||
{
|
||||
TItem widget;
|
||||
if (!m_itemCache.TryGetValue(item.GoId, out widget))
|
||||
{
|
||||
widget = CreateWidget<TItem>(item.gameObject);
|
||||
widget.LoopItem = item;
|
||||
m_itemCache.Add(item.GoId, widget);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取item
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public override TItem GetItem(int index)
|
||||
{
|
||||
for (var i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
|
||||
var item = m_itemCache.GetValueByIndex(i);
|
||||
if (item.GetItemIndex() == index)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取itemList
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<TItem> GetItemList()
|
||||
{
|
||||
m_items.Clear();
|
||||
for (int i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
m_items.Add(m_itemCache.GetValueByIndex(i));
|
||||
}
|
||||
return m_items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前起始索引
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetItemStartIndex()
|
||||
{
|
||||
return LoopRectView.GetItemStartIndex();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Item。
|
||||
/// </summary>
|
||||
/// <param name="index">索引。</param>
|
||||
/// <returns>TItem。</returns>
|
||||
public TItem GetItemByIndex(int index)
|
||||
{
|
||||
return m_itemCache.GetValueByIndex(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新所有item选中状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public void UpdateAllItemSelect()
|
||||
{
|
||||
var index = selectIndex;
|
||||
for (var i = 0; i < m_itemCache.Count; i++)
|
||||
{
|
||||
if (m_itemCache.GetValueByIndex(i) is IListSelectItem item)
|
||||
{
|
||||
item.SetSelected(item.GetItemIndex() == index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateSnapTargetItem()
|
||||
{
|
||||
base.UpdateSnapTargetItem();
|
||||
if (LoopRectView != null && LoopRectView.ItemSnapEnable)
|
||||
{
|
||||
LoopRectView.SetSnapTargetItemIndex(selectIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|