Compare commits

..

57 Commits

Author SHA1 Message Date
ALEXTANG
7914660f8c Update SingletonSystem.cs 2024-05-24 14:00:51 +08:00
ALEXTANG
b00679a276 Merge pull request #75 from SunXuebing/main
调整编辑器模式下模块销毁顺序,解决编辑器退出运行后资源管理器销毁了还被调用问题
2024-05-20 14:17:40 +08:00
sxb
cd9a10ccac Update RootModule.cs
修复条件判断
2024-05-20 13:31:57 +08:00
sxb1067
f11098d32e 调整编辑器模式下模块销毁顺序,解决编辑器退出运行后资源管理器销毁了还被调用问题 2024-05-20 11:25:01 +08:00
ALEXTANGXIAO
db6e715fa6 Update ActorEventDispatcher.cs 2024-05-19 22:03:53 +08:00
ALEXTANG
c2edf71ee4 Update AssetItemObject.cs 2024-05-17 17:55:53 +08:00
ALEXTANG
75af7c22c7 Merge pull request #73 from Senfee-Cheng/main
[fix] 移除 `BuildDLLCommand` 构造函数以尝试解决hotfix dll数组被清除的问题
2024-05-17 15:48:27 +08:00
chengshengfei
2f9edf83bf Merge branch 'main' of github.com:Senfee-Cheng/TEngine 2024-05-17 15:45:26 +08:00
chengshengfei
815095efaf [fix] 移除 BuildDLLCommand 构造函数以尝试解决数组被清除的问题 2024-05-17 15:45:06 +08:00
ALEXTANG
3101a64a48 Merge pull request #72 from Severn17/main
yooasset 微信小游戏设置,详情看yooasset微信小游戏支持解决方案文档
2024-05-16 16:05:41 +08:00
yangshiqi
457e0f36a4 yooasset 微信小游戏设置,详情看yooasset微信小游戏支持解决方案文档 2024-05-16 15:19:32 +08:00
ALEXTANG
0bd30def23 移除示例package文件 2024-05-16 13:16:25 +08:00
ALEXTANG
d24db83c8b Update 99-各平台运行RunAble.md 2024-05-16 12:34:55 +08:00
ALEXTANG
18a2840777 Merge pull request #70 from Senfee-Cheng/main
[Platform] Supports console
2024-05-16 10:26:13 +08:00
chengshengfei
1d901514e1 新的平台支持[Sony Console] 2024-05-16 10:18:03 +08:00
chengshengfei
983279c56d 更新文档,添加新增的支持的平台。 2024-05-16 10:14:22 +08:00
ALEXTANG
e9540c620a Merge pull request #69 from Severn17/main
修改编辑器下webgl  平台名字 宏问题
2024-05-14 17:57:38 +08:00
yangshiqi
39be280d88 修改编辑器下webgl 平台名字 宏问题 2024-05-14 17:45:40 +08:00
ALEXTANG
f9f9122027 单例系统完善生命周期、支持Dispose 2024-05-13 14:09:32 +08:00
ALEXTANG
682a0bd786 Update UnityExtension.cs 2024-05-08 17:11:39 +08:00
ALEXTANG
34c514cae8 Update README.md 2024-05-08 10:31:41 +08:00
ALEXTANG
c707cc1a38 GameApp Shutdown 2024-05-08 10:06:33 +08:00
ALEXTANG
f016fdd0a6 Update ReleaseTools.cs 2024-05-07 20:09:15 +08:00
ALEXTANG
4c0f5a77f9 支持编辑器下EnterPlayMode Options 2024-05-07 18:05:41 +08:00
ALEXTANG
ae0d00424f Update ProfilerDefineSymbols.cs 2024-04-30 17:42:36 +08:00
ALEXTANG
c8ecac5815 Update README.md 2024-04-29 12:27:40 +08:00
ALEXTANG
4f8c1cdfdd 修正SpritePostprocessor处理Atlas的override 2024-04-25 15:43:44 +08:00
ALEXTANG
dff043e075 Update SahderVariantCollect
Update SahderVariantCollect
2024-04-24 11:17:38 +08:00
ALEXTANG
e69dc47b8f 修正编辑器调用转表bat 当前路径的问题
修正编辑器调用转表bat 当前路径的问题
2024-04-17 14:27:28 +08:00
ALEXTANG
fc2ef0714c 设置DefaultYooFolderName为package。原本设置默认为yoo。
设置DefaultYooFolderName为package。原本设置默认为yoo。
2024-04-15 19:58:57 +08:00
ALEXTANG
d75c1c8c93 升级YooAsset->2.1.1、UniTask->2.5.4
升级YooAsset->2.1.1、UniTask->2.5.4
2024-04-15 19:37:42 +08:00
ALEXTANG
83bea559e4 Merge pull request #65 from Senfee-Cheng/main 2024-04-12 18:19:10 +08:00
ALEXTANG
26689639ed Merge pull request #64 from ZemelLing/dev-launcher 2024-04-12 18:17:06 +08:00
chengshengfei
bd6ac5f4da 优化代码。 2024-04-12 10:58:06 +08:00
ZemelLing
70dcb03a3f 确保Launcher打开的main场景,而不是其他名称里包含main的场景。 2024-04-11 13:09:16 +08:00
ALEXTANG
59b3649155 优化框架轮询逻辑 ,用脏数据构建Execute数组。
优化框架轮询逻辑 ,用脏数据构建Execute数组。
2024-04-08 15:37:06 +08:00
ALEXTANG
2c025efe3b 修正预加载流程 2024-04-08 14:41:16 +08:00
ALEXTANG
7ae6ef94ba 修正同时对一个图片进行异步SetSprite的处理
修正同时对一个图片进行异步SetSprite的处理
2024-04-07 15:45:32 +08:00
ALEXTANG
d5bb64b314 资源异步加载从缓存中延迟分帧处理。 2024-04-07 15:33:45 +08:00
ALEXTANG
4c34858ce0 Update SettingsUtils.cs 2024-03-29 15:24:02 +08:00
ALEXTANG
5adb2f83e5 Update AssetBundleCollectorSetting.asset 2024-03-29 14:38:44 +08:00
ALEXTANG
f10a89180e 支持边玩边下载,合理化webgl下的流程
支持边玩边下载,合理化webgl下的流程
2024-03-28 15:55:27 +08:00
ALEXTANG
3e3314858e 优化加载游戏物体接口,常用Parent参数前置,编辑器模式下增加超时保护提示
优化加载游戏物体接口,常用Parent参数前置,编辑器模式下增加超时保护提示
2024-03-25 14:27:42 +08:00
ALEXTANGXIAO
da57ed845f 修正同时对一个资源进行异步加载的处理
修正同时对一个资源进行异步加载的处理
2024-03-24 15:58:57 +08:00
ALEXTANGXIAO
df570f453a Create UnityEditor.iOS_I2Loc.Xcode.dll 2024-03-24 15:50:44 +08:00
ALEXTANG
a500a08a30 更新Luban配置表使用文档 2024-03-19 14:25:48 +08:00
ALEXTANG
2daac0e065 默认一键打包使用ClearAndCopyAll 2024-03-19 14:09:27 +08:00
ALEXTANG
514da6e99e Update README.md 2024-03-18 15:44:29 +08:00
ALEXTANG
7f91241df7 Update Version.cs 2024-03-18 15:06:48 +08:00
ALEXTANG
071974ab4f Update GameLogic.asmdef 2024-03-18 15:05:40 +08:00
ALEXTANG
c01e03ff70 Update AssetBundleCollectorSetting.asset 2024-03-18 15:02:23 +08:00
ALEXTANG
6fec792e05 TEngine全面更新,升级YooAsset2.1.1、UniTask、UIWindow、I2Localization
TEngine全面更新,升级YooAsset2.1.1、UniTask、UIWindow、I2Localization
2024-03-18 14:53:26 +08:00
ALEXTANG
04ecf71eab Update ProcedureLoadAssembly.cs 2024-02-27 12:05:26 +08:00
ALEXTANG
693ca5bb3d 编辑器模式重定向所有热更dll,以防编辑器运行AB时出现两份元数据。
编辑器模式重定向所有热更dll,以防编辑器运行AB时出现两份元数据。
2024-01-25 15:10:30 +08:00
ALEXTANG
90f84a2764 更新README
更新README
2023-12-20 12:43:39 +08:00
ALEXTANG
6107b41770 修正动态添加/异步添加ui组件的脏数据问题
修正动态添加/异步添加ui组件的脏数据问题
2023-12-19 18:24:33 +08:00
ALEXTANG
1423a3716a 编辑器模式重定向所有热更dll,以防编辑器运行AB时出现两份元数据。
编辑器模式重定向所有热更dll,以防编辑器运行AB时出现两份元数据。
2023-12-18 19:49:46 +08:00
1068 changed files with 57072 additions and 35716 deletions

View File

@@ -1,16 +1,16 @@
# TEngine
## TEngine-Runtime
### AOT内核基于Gameframework,最简化以及商业化适配。
### AOT内核基于Gameframework,优化、最简化以及商业化适配。
![image](src/2-1.png)
## AOT游戏框架模块基类。
#### 框架思路为面向接口编程如Resource资源模块开发白皮书为先定义IResourceManager的接口规范然后编写ResourceManager继承框架具体实现(GameFrameworkModule)以及实现接口。最后实现调用层GameFrameworkModuleBase,调用层可以拓展编辑器供开发者自定义模块参数。
#### 框架思路为面向接口编程如Resource资源模块开发白皮书为先定义IResourceManager的接口规范然后编写ResourceManager继承框架具体实现(ModuleImp)以及实现接口。最后实现调用层Module调用层可以拓展编辑器供开发者自定义模块参数。
``` csharp
/// <summary>
/// 游戏框架模块抽象类。GameFrameworkModule为具体框架模块实现。
/// 游戏框架模块抽象类。ModuleImp为具体框架模块实现。
/// </summary>
internal abstract class GameFrameworkModule
internal abstract class ModuleImp
{
/// <summary>
/// 获取游戏框架模块优先级。
@@ -34,16 +34,16 @@ internal abstract class GameFrameworkModule
//=====================================================================//
/// <summary>
/// 游戏框架模块抽象类。GameFrameworkModuleBase 为Mono调用层。
/// 游戏框架模块抽象类。Module 为Mono调用层。
/// </summary>
public abstract class GameFrameworkModuleBase : MonoBehaviour
public abstract class Module : MonoBehaviour
{
/// <summary>
/// 游戏框架模块初始化。
/// </summary>
protected virtual void Awake()
{
GameEntry.RegisterModule(this);
ModuleSystem.RegisterModule(this);
}
}
```

View File

@@ -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配置表目录位于以下目录
![image](src/3-6-1.png)
### 安装luban配置表
1.在TEngine根目录同级克隆下最新的luban-next仓库。
![image](src/3-6-2.png)
2.Tools目录执行build-luban完成
![image](src/3-6-3.png)
3.转表则去luban配置目录执行对应bat
TEngine内置默认使用懒加载配置也支持基于UniTask的异步加载同步加载包括服务器的Task异步加载使用对应转表的bat即可。
### 介绍

View File

@@ -14,3 +14,10 @@
### IOS真机运行
![image](src/Iphone-RunSuccessed.png)
### 索尼 PS5 真机运行
![image](src/Console%20Viewer.png)
![image](src/Console%20Output.png)

16
Books/Donate.md Normal file
View File

@@ -0,0 +1,16 @@
## <strong>Buy me a coffee.
您的赞助会让我们做得更快更好如果觉得TEngine对您有帮助不妨赞助我买杯咖啡吧~
<p align="center">
<img src="src/Donate-微信.jpg" alt="logo" width="384" height="562">
</p>
<p align="center">
<img src="src/Donate-支付宝.jpg" alt="logo" width="384" height="562">
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 74 KiB

BIN
Books/src/3-6-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
Books/src/3-6-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

BIN
Books/src/Donate-微信.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

View File

@@ -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);
}
}

View File

@@ -1,3 +1,6 @@
Cd /d %~dp0
echo %CD%
set WORKSPACE=../..
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
set CONF_ROOT=.

View File

@@ -1,3 +1,6 @@
Cd /d %~dp0
echo %CD%
set WORKSPACE=../..
set LUBAN_DLL=%WORKSPACE%\Tools\Luban\Luban.dll
set CONF_ROOT=.

View File

@@ -1,3 +1,6 @@
Cd /d %~dp0
echo %CD%
set WORKSPACE=../../
set LUBAN_DLL=%WORKSPACE%/Tools/Luban/Luban.dll
set CONF_ROOT=.

View File

@@ -33,9 +33,6 @@
#### TEngine是一个简单(新手友好开箱即用)且强大的Unity框架全平台解决方案,对于需要一套上手快、文档清晰、高性能且可拓展性极强的商业级解决方案的开发者或者团队来说是一个很好的选择。
## <a href="http://1.12.241.46:5000/"><strong>文档快速入门 »</strong></a>
## 文档快速预览 - 5分钟
* [全平台跑通示意](Books/99-各平台运行RunAble.md): 全平台跑通示意。
* [01_介绍](Books/0-介绍.md): 简单介绍。
@@ -46,27 +43,23 @@
* [06_对象池模块](Books/3-4-%E5%AF%B9%E8%B1%A1%E6%B1%A0%E6%A8%A1%E5%9D%97.md): 展示对象池模块概览。
* [07_配置表模块](Books/3-6-%E9%85%8D%E7%BD%AE%E8%A1%A8%E6%A8%A1%E5%9D%97.md): 展示配置表模块概览。
* [08_流程模块](Books/3-7-%E6%B5%81%E7%A8%8B%E6%A8%A1%E5%9D%97.md): 展示商业化流程模块。
* [09_UI模块](Books/3-5-UI模块.md): 展示商业化UI模块。
## <strong>为什么要使用TEngine
0. 开箱即用5分钟即可上手整套开发流程代码整洁思路清晰功能强大。高内聚低耦合。您可以很轻易的把您不需要的模块进行移除替换。
1. 严格按照商业要求使用次世代的HybridClr进行热更新、最佳的Luban配置表(TEngine支持懒加载、异步加载、同步加载配置。)、百万DAU游戏验证过的YooAsset资源框架框架管理资源引用与释放。全平台热更新流程已跑通。
2. 严格按照商业化流程执行的热更新、商业化的UI开发流程、以及资源管理等等设计并实现了YooAsset资源自动释放、支持LRU、ARC严格管理资源内存。
3. C#双端解决方案服务器使用Fantasy是一套源于ETServer但极为简洁性能更强更好上手的一套商业级服务器框架
4. 支持全平台已有项目使用TEngine上架Steam、Wechat-minigame、AppStore。
3. 支持全平台已有项目使用TEngine上架Steam、Wechat-minigame、AppStore
## <strong>资源重要拓展概念
* AssetReference (资源引用标识) 通用加载资源的时候绑定一个引用标识使你无需关心手动Dispose资源句柄。
## <strong>最新的Demo飞机大战位于demo分支
* AssetGroup资源组数据进行资源分组绑定管理内存中的生命周期资源生命周期托管给资源组的根节点进行Dispose。
## <strong>服务器相关
TEngine本身为纯净的客户端。不强绑定任何服务器。但是个人开发以及中小型公司开发双端则推荐C#服务器
* LruCacheTable (Least Recently Used Cache缓存表)
* ArcCacheTable (Adaptive Replacement Cache缓存表)
## <strong>为什么服务器使用C#
Net Core现在已经更新到了8.0的版本在性能和设计上其实是远超JAVA和GO。在JAVAER还在为JVM更新和添加更多功能时其实他们已经被国内大环境所包围了看不到.Net Core的性能之强组件化的结构。国内大环境是JAVA和GO的天下这个不可否认但是国外C#也确实很多。其实.Net Core最大的问题是大多数自己人都不知道他的优点(AOT、JIT混合编译、热重载等等)甚至很多守旧派抵制core。GO喜欢吹性能但其实目前来看除了协程的轻量级大多数性能测试其实不如JAVA和.Net。简单可以说出了C++的性能以外Net Core其实都打得过。
<strong>当然作为商业级解决方案服务器的耦合度也极低,如果不喜欢您也可以很轻松直接移除替换成你的服务器。</strong>
需要服务器可以合并<a href="https://github.com/ALEXTANGXIAO/GameNetty"><strong>GameNetty</strong></a>过来或者分支Fantasy为接好的带有Fantasy服务器的双端分支。
## <strong>项目结构概览
```
@@ -85,6 +78,11 @@ Assets
└── GameLogic // 游戏业务逻辑程序集 [Dll]
├── GameApp.cs // 热更主入口
└── GameApp_RegisterSystem.cs // 热更主入口注册系统
TEngine
├── Editor // TEngine编辑器核心代码
└── Runtime // TEngine运行时核心代码
```
- 必要:项目使用了以下第三方插件,请自行购买导入:
@@ -99,7 +97,14 @@ Assets
#### <a href="https://github.com/focus-creative-games/hybridclr"><strong>HybridCLR</strong></a> - 特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案
#### <a href="https://github.com/qq362946/Fantasy"><strong>Fantasy</strong></a> - Fantasy是一套源于ETServer但极为简洁性能更强,更好上手的一套商业级服务器框架。
#### <a href="https://github.com/qq362946/Fantasy"><strong>Fantasy</strong></a> - Fantasy是一套源于ETServer但极为简洁更好上手的一套商业级服务器框架。
#### <a href="https://github.com/ALEXTANGXIAO/GameNetty"><strong>GameNetty</strong></a> - GameNetty是一套源于ETServer首次拆分最新的ET8.1的前后端解决方案客户端最精简大约750k完美做成包的形式几乎零成本 无侵入的嵌入进你的框架。
## <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>
## <strong>Buy me a 奶茶.
[您的赞助会让我们做得更快更好如果觉得TEngine对您有帮助不妨请我可爱的女儿买杯奶茶吧~](Books/Donate.md)

View File

@@ -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

View File

@@ -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

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: a363de58f5d6e9e438b2b9a692187f6e
guid: c91b064c2cd7a34448ae0d6d7ee58e7f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
mainObjectFileID: 4343727234628468602
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: b9eaf6bdacd0683468b1dd697e3d2bce
SpriteAtlasImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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
}
]

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2de5a58f37a4ae64e804f150144da809
guid: 3b549395c8849674b9cafbbf4c694e57
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 40c870edb8e84064a8be2d56acb8bbc0
guid: 4c9eb26aee01e8643bd4e6dc965d3366
folderAsset: yes
DefaultImporter:
externalObjects: {}

View 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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b763f43bfb633944aa8955535b965c1f
guid: f069f2f03dfa55843a74dedc551eefb2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000

View File

@@ -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;
}
}
}
}

View File

@@ -0,0 +1,108 @@
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()
{
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;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bc365e281d234e61891bf9f922a0897a
timeCreated: 1715574965

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4ad00b596d0743a4b04591fe52087d0f
timeCreated: 1715574577

View File

@@ -171,7 +171,7 @@ namespace GameLogic
CurState = false;
}
public override void OnDestroy()
protected override void OnDestroy()
{
RemoveNotifyBind();
}

View File

@@ -516,7 +516,7 @@ namespace GameLogic
{
if (paramList is { Count: > 0 })
{
return false;
return true;
}
return false;

View File

@@ -7,14 +7,14 @@ namespace GameLogic
public class RedNoteWidget : UIWidget
{
#region
public override void ScriptGenerator()
protected override void ScriptGenerator()
{
}
#endregion
private Image m_image;
public RedNoteBehaviour m_redNote;
public override void OnCreate()
protected override void OnCreate()
{
m_redNote = CreateWidget<RedNoteBehaviour>(gameObject);
m_image = gameObject.GetComponent<Image>();
@@ -42,10 +42,10 @@ namespace GameLogic
public void SetSprite(string sprite)
{
m_image.SetSprite(sprite);
// m_image.SetSprite(sprite);
}
public override void OnUpdate()
protected override void OnUpdate()
{
/*if (!m_redNote.CurState)
{

View File

@@ -377,7 +377,7 @@ namespace GameLogic
private GridItemPool TryCreateItemPool(string itemPrefabName)
{
string resPath = itemPrefabName;
GameObject go = GameModule.Resource.LoadAsset<GameObject>(resPath, _containerTrans);
GameObject go = GameModule.Resource.LoadGameObject(resPath, parent: _containerTrans);
if (go != null)
{
go.SetActive(false);

View File

@@ -669,7 +669,7 @@ namespace GameLogic
private ItemPool TryCreateItemPool(string itemPrefabName)
{
string resPath = itemPrefabName;
GameObject go = GameModule.Resource.LoadAsset<GameObject>(resPath, _containerTrans);
GameObject go = GameModule.Resource.LoadGameObject(resPath, parent: _containerTrans);
if (go != null)
{
go.SetActive(false);

View File

@@ -55,7 +55,7 @@ namespace GameLogic
}
}
public override void BindMemberProperty()
protected override void BindMemberProperty()
{
m_selectNode = FindChild("SelectNode");
m_noSelectNode = FindChild("NoSelectNode");

View File

@@ -86,7 +86,7 @@ namespace GameLogic
{
}
public override void RegisterEvent()
protected override void RegisterEvent()
{
base.RegisterEvent();
AddSelectEvt();

View File

@@ -30,19 +30,19 @@ namespace GameLogic
/// </summary>
public List<TItem> items => m_items;
public override void BindMemberProperty()
protected override void BindMemberProperty()
{
base.BindMemberProperty();
LoopRectView = rectTransform.GetComponent<LoopGridView>();
}
public override void OnCreate()
protected override void OnCreate()
{
base.OnCreate();
LoopRectView.InitGridView(0, OnGetItemByIndex);
}
public override void OnDestroy()
protected override void OnDestroy()
{
base.OnDestroy();
m_itemCache.Clear();

View File

@@ -10,13 +10,13 @@ namespace GameLogic
private GameFrameworkDictionary<int, T> m_itemCache = new GameFrameworkDictionary<int, T>();
public override void BindMemberProperty()
protected override void BindMemberProperty()
{
base.BindMemberProperty();
LoopRectView = this.rectTransform.GetComponent<LoopListView>();
}
public override void OnDestroy()
protected override void OnDestroy()
{
base.OnDestroy();
m_itemCache.Clear();

View File

@@ -31,19 +31,19 @@ namespace GameLogic
/// </summary>
public List<TItem> items => m_items;
public override void BindMemberProperty()
protected override void BindMemberProperty()
{
base.BindMemberProperty();
LoopRectView = rectTransform.GetComponent<LoopListView>();
}
public override void OnCreate()
protected override void OnCreate()
{
base.OnCreate();
LoopRectView.InitListView(0, OnGetItemByIndex);
}
public override void OnDestroy()
protected override void OnDestroy()
{
base.OnDestroy();
m_itemCache.Clear();

View File

@@ -34,6 +34,7 @@ namespace GameLogic
object obj = Activator.CreateInstance(type, mgr.Dispatcher);
mgr.Init();
mgr.RegWrapInterface(obj.GetType().GetInterfaces()[0]?.FullName, obj);
}
}

View File

@@ -19,7 +19,7 @@ public partial class GameApp:Singleton<GameApp>
_hotfixAssembly = (List<Assembly>)objects[0];
Log.Warning("======= 看到此条日志代表你成功运行了热更新代码 =======");
Log.Warning("======= Entrance GameApp =======");
Instance.Init();
Instance.Active();
Instance.Start();
Utility.Unity.AddUpdateListener(Instance.Update);
Utility.Unity.AddFixedUpdateListener(Instance.FixedUpdate);
@@ -46,6 +46,7 @@ public partial class GameApp:Singleton<GameApp>
/// <param name="shutdownType">关闭游戏框架类型。</param>
public static void Shutdown(ShutdownType shutdownType)
{
Log.Info("GameApp Shutdown");
if (shutdownType == ShutdownType.None)
{
return;
@@ -59,8 +60,9 @@ public partial class GameApp:Singleton<GameApp>
Utility.Unity.RemoveDestroyListener(Instance.OnDestroy);
Utility.Unity.RemoveOnDrawGizmosListener(Instance.OnDrawGizmos);
Utility.Unity.RemoveOnApplicationPauseListener(Instance.OnApplicationPause);
return;
}
SingletonSystem.Release();
}
private void Start()
@@ -128,6 +130,7 @@ public partial class GameApp:Singleton<GameApp>
var logic = listLogic[i];
logic.OnDestroy();
}
Shutdown(ShutdownType.Restart);
}
private void OnDrawGizmos()

View File

@@ -7,7 +7,7 @@ public partial class GameApp
{
private List<ILogicSys> _listLogicMgr;
private void Init()
public override void Active()
{
CodeTypes.Instance.Init(_hotfixAssembly.ToArray());
EventInterfaceHelper.Init();

View File

@@ -3,12 +3,11 @@
"rootNamespace": "GameLogic",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:15fc0a57446b3144c949da3e2b9737a9",
"GUID:cbb0d51b565003841ae81cdbaf747114",
"GUID:8f58f15387c7a6f4fad9857024eb47f7",
"GUID:24c092aee38482f4e80715eaa8148782",
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:f51ebe6a0ceec4240a699833d6309b23"
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:e34a5702dd353724aa315fb8011f08c3"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -2,12 +2,9 @@
"name": "GameProto",
"rootNamespace": "",
"references": [
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:cbb0d51b565003841ae81cdbaf747114",
"GUID:24c092aee38482f4e80715eaa8148782",
"GUID:756335c0388f7114790e504ed368ae1d",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:e34a5702dd353724aa315fb8011f08c3"
"GUID:f51ebe6a0ceec4240a699833d6309b23"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,11 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GameProto
{
public class GameProto_Empty
{
}
}

View File

@@ -56,8 +56,8 @@ namespace GameMain
/// </summary>
public static void HideAll()
{
GameModule.UI.CloseWindow<UILoadTip>();
GameModule.UI.CloseWindow<UILoadUpdate>();
GameModule.UI.CloseUI<UILoadTip>();
GameModule.UI.CloseUI<UILoadUpdate>();
}
}
}

View File

@@ -25,7 +25,7 @@ namespace GameMain
private Text m_textInfo;
private Button m_btnIgnore;
private Button m_btnUpdate;
public override void ScriptGenerator()
protected override void ScriptGenerator()
{
m_btnPackage = FindChildComponent<Button>("BgImage/m_btnPackage");
m_textTittle = FindChildComponent<Text>("BgImage/m_textTittle");
@@ -81,8 +81,18 @@ namespace GameMain
#endregion
public override void OnRefresh()
protected override void OnRefresh()
{
OnOk = (Action)userDatas[1];
OnCancel = (Action)userDatas[2];
ShowType = (MessageShowType)userDatas[3];
var loadStyleUI = gameObject.GetComponent<LoadStyle>();
if (loadStyleUI)
{
loadStyleUI.SetStyle((LoadStyle.StyleEnum)userDatas[4]);
}
base.OnRefresh();
m_btnIgnore.gameObject.SetActive(false);
m_btnPackage.gameObject.SetActive(false);
@@ -121,23 +131,7 @@ namespace GameMain
Action onCancel = null,
Action onPackage = null)
{
var operation = GameModule.UI.ShowUI<UILoadTip>(desc);
if (operation == null || operation.Window == null)
{
return;
}
var ui = operation.Window as UILoadTip;
ui.OnOk = onOk;
ui.OnCancel = onCancel;
ui.ShowType = showtype;
ui.OnRefresh();
var loadStyleUI = ui.gameObject.GetComponent<LoadStyle>();
if (loadStyleUI)
{
loadStyleUI.SetStyle(style);
}
GameModule.UI.ShowUI<UILoadTip>(desc,onOk,onCancel,showtype,style);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace GameMain
private Button m_btnClear;
private Text m_textAppid;
private Text m_textResid;
public override void ScriptGenerator()
protected override void ScriptGenerator()
{
m_imgBackGround = FindChildComponent<Image>("m_imgBackGround");
m_textDesc = FindChildComponent<Text>("m_textDesc");
@@ -28,7 +28,7 @@ namespace GameMain
}
#endregion
public override void OnCreate()
protected override void OnCreate()
{
base.OnCreate();
LoadUpdateLogic.Instance.DownloadCompleteAction += DownLoad_Complete_Action;
@@ -38,13 +38,13 @@ namespace GameMain
m_btnClear.gameObject.SetActive(true);
}
public override void RegisterEvent()
protected override void RegisterEvent()
{
base.RegisterEvent();
AddUIEvent(RuntimeId.ToRuntimeId("RefreshVersion"),RefreshVersion);
}
public override void OnRefresh()
protected override void OnRefresh()
{
base.OnRefresh();
}
@@ -123,7 +123,7 @@ namespace GameMain
m_scrollbarProgress.size = progress;
}
public override void OnDestroy()
protected override void OnDestroy()
{
base.OnDestroy();
OnStop(null);

View File

@@ -28,6 +28,8 @@ namespace GameMain
}
private async UniTaskVoid InitPackage(ProcedureOwner procedureOwner)
{
try
{
if (GameModule.Resource.PlayMode == EPlayMode.HostPlayMode ||
GameModule.Resource.PlayMode == EPlayMode.WebPlayMode)
@@ -52,11 +54,7 @@ namespace GameMain
}
}
var initializationOperation = GameModule.Resource.InitPackage();
await UniTask.Delay(TimeSpan.FromSeconds(1f));
await initializationOperation.ToUniTask();
var initializationOperation = await GameModule.Resource.InitPackage();
if (initializationOperation.Status == EOperationStatus.Succeed)
{
@@ -80,7 +78,8 @@ namespace GameMain
ChangeState<ProcedureInitResources>(procedureOwner);
}
// 可更新模式。
else if (playMode == EPlayMode.HostPlayMode)
else if (playMode == EPlayMode.HostPlayMode ||
playMode == EPlayMode.WebPlayMode)
{
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate);
@@ -88,12 +87,6 @@ namespace GameMain
Log.Info("Updatable resource mode detected.");
ChangeState<ProcedureUpdateVersion>(procedureOwner);
}
// 可更新模式。
else if (playMode == EPlayMode.WebPlayMode)
{
Log.Info("WebPlayMode resource mode detected.");
ChangeState<ProcedurePreload>(procedureOwner);
}
else
{
Log.Error("UnKnow resource mode detected Please check???");
@@ -116,6 +109,27 @@ namespace GameMain
, () => { Retry(procedureOwner); }, UnityEngine.Application.Quit);
}
}
catch (Exception e)
{
OnInitPackageFailed(procedureOwner, e.Message);
}
}
private void OnInitPackageFailed(ProcedureOwner procedureOwner, string message)
{
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate);
Log.Error($"{message}");
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate, $"资源初始化失败!");
UILoadTip.ShowMessageBox($"资源初始化失败!点击确认重试 \n \n <color=#FF0000>原因{message}</color>", MessageShowType.TwoButton,
LoadStyle.StyleEnum.Style_Retry
, () => { Retry(procedureOwner); },
Application.Quit);
}
private void Retry(ProcedureOwner procedureOwner)
{

View File

@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
#if ENABLE_HYBRIDCLR
using HybridCLR;
#endif
using UnityEngine;
using TEngine;
using System.Reflection;
@@ -15,11 +17,6 @@ namespace GameMain
/// </summary>
public class ProcedureLoadAssembly : ProcedureBase
{
/// <summary>
/// 是否需要加载热更新DLL
/// </summary>
public bool NeedLoadDll => (int)GameModule.Resource.PlayMode > (int)EPlayMode.EditorSimulateMode;
private bool m_enableAddressable = true;
public override bool UseNativeDialog => true;
private int m_LoadAssetCount;
@@ -59,7 +56,7 @@ namespace GameMain
m_LoadMetadataAssemblyComplete = true;
}
if (!NeedLoadDll || GameModule.Resource.PlayMode == EPlayMode.EditorSimulateMode)
if (!SettingsUtils.HybridCLRCustomGlobalSettings.Enable || GameModule.Resource.PlayMode == EPlayMode.EditorSimulateMode)
{
m_MainLogicAssembly = GetMainLogicAssembly();
}
@@ -81,7 +78,7 @@ namespace GameMain
Log.Debug($"LoadAsset: [ {assetLocation} ]");
m_LoadAssetCount++;
GameModule.Resource.LoadAssetAsync<TextAsset>(assetLocation,LoadAssetSuccess);
GameModule.Resource.LoadAsset<TextAsset>(assetLocation,LoadAssetSuccess);
}
m_LoadAssemblyWait = true;
@@ -116,8 +113,7 @@ namespace GameMain
{
ChangeState<ProcedureStartGame>(m_procedureOwner);
#if UNITY_EDITOR
m_MainLogicAssembly = AppDomain.CurrentDomain.GetAssemblies().
First(assembly => $"{assembly.GetName().Name}.dll" == SettingsUtils.HybridCLRCustomGlobalSettings.LogicMainDllName);
m_MainLogicAssembly = GetMainLogicAssembly();
#endif
if (m_MainLogicAssembly == null)
{
@@ -142,6 +138,7 @@ namespace GameMain
private Assembly GetMainLogicAssembly()
{
m_HotfixAssemblys.Clear();
Assembly mainLogicAssembly = null;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
@@ -171,20 +168,19 @@ namespace GameMain
/// <summary>
/// 加载代码资源成功回调。
/// </summary>
/// <param name="assetOperationHandle">资源操作句柄。</param>
private void LoadAssetSuccess(AssetOperationHandle assetOperationHandle)
/// <param name="textAsset">代码资产。</param>
private void LoadAssetSuccess(TextAsset textAsset)
{
m_LoadAssetCount--;
var assetName = assetOperationHandle.AssetObject.name;
Log.Debug($"LoadAssetSuccess, assetName: [ {assetName} ]");
var textAsset = assetOperationHandle.AssetObject as TextAsset;
if (textAsset == null)
{
Log.Warning($"Load text asset [ {assetName} ] failed.");
Log.Warning($"Load Assembly failed.");
return;
}
var assetName = textAsset.name;
Log.Debug($"LoadAssetSuccess, assetName: [ {assetName} ]");
try
{
var assembly = Assembly.Load(textAsset.bytes);
@@ -205,7 +201,7 @@ namespace GameMain
{
m_LoadAssemblyComplete = m_LoadAssemblyWait && 0 == m_LoadAssetCount;
}
assetOperationHandle.Dispose();
GameModule.Resource.UnloadAsset(textAsset);
}
/// <summary>
@@ -239,7 +235,7 @@ namespace GameMain
Log.Debug($"LoadMetadataAsset: [ {assetLocation} ]");
m_LoadMetadataAssetCount++;
GameModule.Resource.LoadAssetAsync<TextAsset>(assetLocation,LoadMetadataAssetSuccess);
GameModule.Resource.LoadAsset<TextAsset>(assetLocation,LoadMetadataAssetSuccess);
}
m_LoadMetadataAssemblyWait = true;
}
@@ -247,27 +243,29 @@ namespace GameMain
/// <summary>
/// 加载元数据资源成功回调。
/// </summary>
/// <param name="assetOperationHandle">资源操作句柄。</param>
private unsafe void LoadMetadataAssetSuccess(AssetOperationHandle assetOperationHandle)
/// <param name="textAsset">代码资产。</param>
private unsafe void LoadMetadataAssetSuccess(TextAsset textAsset)
{
m_LoadMetadataAssetCount--;
string assetName = assetOperationHandle.AssetObject.name;
Log.Debug($"LoadMetadataAssetSuccess, assetName: [ {assetName} ]");
var textAsset = assetOperationHandle.AssetObject as TextAsset;
if (null == textAsset)
{
Log.Debug($"LoadMetadataAssetSuccess:Load text asset [ {assetName} ] failed.");
Log.Debug($"LoadMetadataAssetSuccess:Load Metadata failed.");
return;
}
string assetName = textAsset.name;
Log.Debug($"LoadMetadataAssetSuccess, assetName: [ {assetName} ]");
try
{
byte[] dllBytes = textAsset.bytes;
fixed (byte* ptr = dllBytes)
{
#if ENABLE_HYBRIDCLR
// 加载assembly对应的dll会自动为它hook。一旦Aot泛型函数的native函数不存在用解释器版本代码
HomologousImageMode mode = HomologousImageMode.SuperSet;
LoadImageErrorCode err = (LoadImageErrorCode)HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(dllBytes,mode);
Log.Warning($"LoadMetadataForAOTAssembly:{assetName}. mode:{mode} ret:{err}");
#endif
}
}
catch (Exception e)
@@ -279,8 +277,8 @@ namespace GameMain
finally
{
m_LoadMetadataAssemblyComplete = m_LoadMetadataAssemblyWait && 0 == m_LoadMetadataAssetCount;
}
}
GameModule.Resource.UnloadAsset(textAsset);
}
}
}

View File

@@ -22,7 +22,17 @@ namespace GameMain
private readonly bool _needProLoadConfig = true;
private bool _hadInitConfigXml = false;
/// <summary>
/// 预加载回调。
/// </summary>
private LoadAssetCallbacks m_PreLoadAssetCallbacks;
protected override void OnInit(ProcedureOwner procedureOwner)
{
base.OnInit(procedureOwner);
m_PreLoadAssetCallbacks = new LoadAssetCallbacks(OnPreLoadAssetSuccess, OnPreLoadAssetFailure);
}
protected override void OnEnter(ProcedureOwner procedureOwner)
{
@@ -30,16 +40,11 @@ namespace GameMain
_loadedFlag.Clear();
if (GameModule.Resource.PlayMode == EPlayMode.EditorSimulateMode)
{
_hadInitConfigXml = true;
}
UILoadMgr.Show(UIDefine.UILoadUpdate, Utility.Text.Format(LoadText.Instance.Label_Load_Load_Progress, 0));
GameEvent.Send("UILoadUpdate.RefreshVersion");
PreloadResources().Forget();
PreloadResources();
}
protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
@@ -87,11 +92,6 @@ namespace GameMain
return;
}
if (_hadInitConfigXml == false)
{
return;
}
ChangeState<ProcedureLoadAssembly>(procedureOwner);
}
@@ -110,61 +110,50 @@ namespace GameMain
callback?.Invoke();
}
private async UniTaskVoid PreloadResources()
private void PreloadResources()
{
await SmoothValue(1f, 1.2f).ToUniTask(GameModule.Procedure);
await UniTask.Delay(TimeSpan.FromSeconds(2.5f));
if (_needProLoadConfig)
{
LoadAllConfig();
}
else
{
_hadInitConfigXml = true;
}
}
private void LoadAllConfig()
{
if (GameModule.Resource.PlayMode == EPlayMode.EditorSimulateMode)
{
_hadInitConfigXml = true;
return;
}
AssetInfo[] assetInfos = GameModule.Resource.GetAssetInfos("PRELOAD");
foreach (var assetInfo in assetInfos)
{
LoadConfig(assetInfo.Address);
PreLoad(assetInfo.Address);
}
#if UNITY_WEBGL
AssetInfo[] webAssetInfos = GameModule.Resource.GetAssetInfos("WEBGL_PRELOAD");
foreach (var assetInfo in webAssetInfos)
{
LoadConfig(assetInfo.Address);
PreLoad(assetInfo.Address);
}
#endif
_hadInitConfigXml = true;
}
private void LoadConfig(string configName)
private void PreLoad(string location)
{
_loadedFlag.Add(configName, false);
GameModule.Resource.LoadAssetAsync<TextAsset>(configName, OnLoadSuccess);
_loadedFlag.Add(location, false);
GameModule.Resource.LoadAssetAsync(location, typeof(UnityEngine.Object), m_PreLoadAssetCallbacks, null);
}
private void OnLoadSuccess(AssetOperationHandle assetOperationHandle)
private void OnPreLoadAssetFailure(string assetName, LoadResourceStatus status, string errormessage, object userdata)
{
if (assetOperationHandle == null)
Log.Warning("Can not preload asset from '{0}' with error message '{1}'.", assetName, errormessage);
_loadedFlag[assetName] = true;
}
private void OnPreLoadAssetSuccess(string assetName, object asset, float duration, object userdata)
{
return;
}
var location = assetOperationHandle.GetAssetInfo().Address;
_loadedFlag[location] = true;
GameModule.Resource.PushPreLoadAsset(location, assetOperationHandle.AssetObject);
Log.Info("Load config '{0}' OK.", location);
assetOperationHandle.Dispose();
Log.Debug("Success preload asset from '{0}' duration '{1}'.", assetName, duration);
_loadedFlag[assetName] = true;
}
}
}

View File

@@ -10,11 +10,6 @@ namespace GameMain
{
public override bool UseNativeDialog => true;
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
}
protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);

View File

@@ -35,6 +35,14 @@ namespace GameMain
//更新成功
//注意:保存资源版本号作为下次默认启动的版本!
operation.SavePackageVersion();
if (GameModule.Resource.PlayMode == EPlayMode.WebPlayMode ||
GameModule.Resource.UpdatableWhilePlaying)
{
// 边玩边下载还可以拓展首包支持。
ChangeState<ProcedurePreload>(procedureOwner);
return;
}
ChangeState<ProcedureCreateDownloader>(procedureOwner);
}
else

View File

@@ -1,14 +1,49 @@
fileFormatVersion: 2
guid: 5651992cdad94894a3af7dc3f1da9170
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: N3DS
second:
enabled: 1
settings: {}
- first:
: PSM
second:
enabled: 1
settings: {}
- first:
: PSP2
second:
enabled: 1
settings: {}
- first:
: SamsungTV
second:
enabled: 1
settings: {}
- first:
: Tizen
second:
enabled: 1
settings: {}
- first:
: WiiU
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings:
Exclude Android: 1
@@ -33,45 +68,46 @@ PluginImporter:
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
N3DS:
- first:
PS4: PS4
second:
enabled: 1
settings: {}
PS4:
- first:
Standalone: Win64
second:
enabled: 1
settings: {}
PSM:
- first:
WebGL: WebGL
second:
enabled: 1
settings: {}
PSP2:
enabled: 1
settings: {}
SamsungTV:
enabled: 1
settings: {}
Tizen:
enabled: 1
settings: {}
WebGL:
enabled: 1
settings: {}
WiiU:
enabled: 1
settings: {}
WindowsStoreApps:
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: AnyCPU
XboxOne:
- first:
XboxOne: XboxOne
second:
enabled: 1
settings: {}
iOS:
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
tvOS:
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:

View File

@@ -1,14 +1,49 @@
fileFormatVersion: 2
guid: 5978f8f3dd274e848fbb7a123bde1fb9
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: N3DS
second:
enabled: 1
settings: {}
- first:
: PSM
second:
enabled: 1
settings: {}
- first:
: PSP2
second:
enabled: 1
settings: {}
- first:
: SamsungTV
second:
enabled: 1
settings: {}
- first:
: Tizen
second:
enabled: 1
settings: {}
- first:
: WiiU
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings:
Exclude Android: 1
@@ -33,45 +68,46 @@ PluginImporter:
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
N3DS:
- first:
PS4: PS4
second:
enabled: 1
settings: {}
PS4:
- first:
Standalone: Win64
second:
enabled: 1
settings: {}
PSM:
- first:
WebGL: WebGL
second:
enabled: 1
settings: {}
PSP2:
enabled: 1
settings: {}
SamsungTV:
enabled: 1
settings: {}
Tizen:
enabled: 1
settings: {}
WebGL:
enabled: 1
settings: {}
WiiU:
enabled: 1
settings: {}
WindowsStoreApps:
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: AnyCPU
XboxOne:
- first:
XboxOne: XboxOne
second:
enabled: 1
settings: {}
iOS:
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
tvOS:
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:

View File

@@ -1,17 +1,49 @@
fileFormatVersion: 2
guid: d2a8f0021d6b47c5923d8972dfb81ef1
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
Android:
- first:
: Linux
second:
enabled: 1
settings: {}
- first:
: LinuxUniversal
second:
enabled: 1
settings: {}
- first:
: OSXIntel
second:
enabled: 1
settings: {}
- first:
: OSXIntel64
second:
enabled: 1
settings: {}
- first:
: PSM
second:
enabled: 0
settings: {}
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings:
Exclude Android: 0
@@ -36,38 +68,39 @@ PluginImporter:
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
Linux:
- first:
Standalone: Linux64
second:
enabled: 1
settings: {}
Linux64:
settings:
CPU:
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings: {}
LinuxUniversal:
settings:
CPU:
- first:
Standalone: Win
second:
enabled: 1
settings: {}
OSXIntel:
enabled: 1
settings: {}
OSXIntel64:
enabled: 1
settings: {}
OSXUniversal:
enabled: 1
settings: {}
PSM:
settings:
CPU:
- first:
Standalone: Win64
second:
enabled: 0
settings: {}
Win:
enabled: 1
settings: {}
Win64:
enabled: 1
settings: {}
WindowsStoreApps:
settings:
CPU:
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU

View File

@@ -1,17 +1,49 @@
fileFormatVersion: 2
guid: 1e0a9643dc0d4b46bf2321f72c4e503e
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
Android:
- first:
: Linux
second:
enabled: 1
settings: {}
- first:
: LinuxUniversal
second:
enabled: 1
settings: {}
- first:
: OSXIntel
second:
enabled: 1
settings: {}
- first:
: OSXIntel64
second:
enabled: 1
settings: {}
- first:
: PSM
second:
enabled: 0
settings: {}
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings:
Exclude Android: 0
@@ -36,38 +68,39 @@ PluginImporter:
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
Linux:
- first:
Standalone: Linux64
second:
enabled: 1
settings: {}
Linux64:
settings:
CPU:
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings: {}
LinuxUniversal:
settings:
CPU:
- first:
Standalone: Win
second:
enabled: 1
settings: {}
OSXIntel:
enabled: 1
settings: {}
OSXIntel64:
enabled: 1
settings: {}
OSXUniversal:
enabled: 1
settings: {}
PSM:
settings:
CPU:
- first:
Standalone: Win64
second:
enabled: 0
settings: {}
Win:
enabled: 1
settings: {}
Win64:
enabled: 1
settings: {}
WindowsStoreApps:
settings:
CPU:
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU

View File

@@ -708,11 +708,12 @@ MonoBehaviour:
m_GameObject: {fileID: 914171637}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ecea0510f57e4f30a2e44abbc8da5b0a, type: 3}
m_Script: {fileID: 11500000, guid: 706e6317a59f61044b2805be79f6b284, type: 3}
m_Name:
m_EditorClassIdentifier:
m_LocalizationHelperTypeName: TEngine.DefaultLocalizationHelper
m_CustomLocalizationHelper: {fileID: 0}
m_InnerLocalizationCSV: {fileID: 0}
m_AllLanguage: []
m_UseRuntimeModule: 1
--- !u!1 &964133196
GameObject:
m_ObjectHideFlags: 0
@@ -770,6 +771,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 965975541}
- component: {fileID: 965975543}
- component: {fileID: 965975542}
m_Layer: 0
m_Name: Resource
@@ -802,19 +804,36 @@ MonoBehaviour:
m_GameObject: {fileID: 965975540}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 35b9a0ed33eb4c928f1d408679c9ef51, type: 3}
m_Script: {fileID: 11500000, guid: 6153d27eaaa74c0e9a00c9eb273cc21c, type: 3}
m_Name:
m_EditorClassIdentifier:
packageName: DefaultPackage
m_CheckCanReleaseInterval: 30
m_AutoReleaseInterval: 60
--- !u!114 &965975543
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 965975540}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: da56eb8e282380a478681f0d4445502d, type: 3}
m_Name:
m_EditorClassIdentifier:
m_MinUnloadUnusedAssetsInterval: 60
m_MaxUnloadUnusedAssetsInterval: 300
PackageName: DefaultPackage
playMode: 1
verifyLevel: 1
readWritePathType: 0
minUnloadUnusedAssetsInterval: 60
maxUnloadUnusedAssetsInterval: 300
milliseconds: 30
downloadingMaxNum: 3
failedTryAgain: 3
adaptiveReplacementCacheCapacity: 32
VerifyLevel: 1
m_ReadWritePathType: 0
Milliseconds: 30
m_DownloadingMaxNum: 10
m_FailedTryAgain: 3
m_AssetAutoReleaseInterval: 60
m_AssetCapacity: 64
m_AssetExpireTime: 60
m_AssetPriority: 0
--- !u!1 &1029867561
GameObject:
m_ObjectHideFlags: 0

View File

@@ -1,22 +0,0 @@
%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: 09788b4733bab2d4792fdd5d28e7653c, type: 3}
m_Name: AssetBundleBuilderSetting
m_EditorClassIdentifier:
BuildPipeline: 1
BuildMode: 1
BuildPackage: DefaultPackage
CompressOption: 2
OutputNameStyle: 1
CopyBuildinFileOption: 1
CopyBuildinFileTags:
EncyptionClassName: FileStreamEncryption

View File

@@ -13,14 +13,16 @@ MonoBehaviour:
m_Name: AssetBundleCollectorSetting
m_EditorClassIdentifier:
ShowPackageView: 0
EnableAddressable: 1
LocationToLower: 0
IncludeAssetGUID: 0
UniqueBundleName: 0
ShowEditorAlias: 0
UniqueBundleName: 0
Packages:
- PackageName: DefaultPackage
PackageDesc: "\u9ED8\u8BA4\u8D44\u6E90\u5305"
EnableAddressable: 1
LocationToLower: 0
IncludeAssetGUID: 0
IgnoreDefaultType: 1
AutoCollectShaders: 1
Groups:
- GroupName: Actor
GroupDesc: "\u89D2\u8272"
@@ -143,8 +145,8 @@ MonoBehaviour:
CollectorGUID: 2a4bceb84ed685447ace957f497eb810
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackShaderVariants
FilterRuleName: CollectShaderVariants
PackRuleName: PackSeparately
FilterRuleName: CollectAll
AssetTags:
UserData:
- GroupName: UI

View File

@@ -13,3 +13,4 @@ MonoBehaviour:
m_Name: YooAssetSettings
m_EditorClassIdentifier:
ManifestFileName: PackageManifest
DefaultYooFolderName: package

View File

@@ -1,17 +0,0 @@
%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: 44454e58a49818040a1aef5799e71b30, type: 3}
m_Name: ShaderVariantCollectorSetting
m_EditorClassIdentifier:
SavePath: Assets/ShaderVariants/MyShaderVariants.shadervariants
CollectPackage: DefaultPackage
ProcessCapacity: 1000

View File

@@ -8,19 +8,19 @@ namespace TEngine.Editor
public class ProfilerDefineSymbols
{
private const string EnableFirstProfiler = "FIRST_PROFILER";
private const string EnableDinProFiler = "T_PROFILER";
private const string EnableTProFiler = "T_PROFILER";
private static readonly string[] AllProfilerDefineSymbols = new string[]
{
EnableFirstProfiler,
EnableDinProFiler,
EnableTProFiler,
};
/// <summary>
/// 禁用所有日志脚本宏定义。
/// </summary>
[MenuItem("TEngine/Profiler Define Symbols/Disable All Profiler", false, 30)]
public static void DisableAllLogs()
public static void DisableAllProfiler()
{
foreach (string aboveLogScriptingDefineSymbol in AllProfilerDefineSymbols)
{
@@ -32,9 +32,9 @@ namespace TEngine.Editor
/// 开启所有日志脚本宏定义。
/// </summary>
[MenuItem("TEngine/Profiler Define Symbols/Enable All Profiler", false, 31)]
public static void EnableAllLogs()
public static void EnableAllProfiler()
{
DisableAllLogs();
DisableAllProfiler();
foreach (string aboveLogScriptingDefineSymbol in AllProfilerDefineSymbols)
{
ScriptingDefineSymbols.AddScriptingDefineSymbol(aboveLogScriptingDefineSymbol);

View File

@@ -14,7 +14,8 @@ namespace TEngine.Editor
BuildTargetGroup.iOS,
BuildTargetGroup.Android,
BuildTargetGroup.WSA,
BuildTargetGroup.WebGL
BuildTargetGroup.WebGL,
BuildTargetGroup.PS5
};
/// <summary>

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 654d71b5910a48b686279708db8865e2
timeCreated: 1710744353

View File

@@ -0,0 +1,20 @@
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor
{
public static class LubanTools
{
[MenuItem("TEngine/Tools/Luban 转表")]
public static void BuildLubanExcel()
{
Application.OpenURL(Application.dataPath + @"/../../Configs/GameConfig/gen_code_bin_to_project_lazyload.bat");
}
[MenuItem("TEngine/Tools/打开表格目录")]
public static void OpenConfigFolder()
{
OpenFolderHelper.Execute(Application.dataPath + @"/../../Configs/GameConfig");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0d51346d2ce24afaba0b8c9e8095fff4
timeCreated: 1708583331

View File

@@ -13,6 +13,7 @@ Example:
************************************************************************************************************/
#endregion
using HybridCLR.Editor.Settings;
using System;
using System.Collections;
using System.Collections.Generic;

View File

@@ -8,11 +8,28 @@ public static class SyncAssemblyContent
{
public static void RefreshAssembly()
{
SettingsUtils.SetHybridCLRHotUpdateAssemblies(HybridCLR.Editor.SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
SettingsUtils.SetHybridCLRAOTMetaAssemblies(HybridCLR.Editor.SettingsUtil.AOTAssemblyNames);
SettingsUtils.HybridCLRCustomGlobalSettings.Enable = HybridCLR.Editor.SettingsUtil.Enable;
var hotUpdateAssemblyFiles = HybridCLR.Editor.SettingsUtil.HotUpdateAssemblyFilesIncludePreserved;
var aotAssemblyNames = HybridCLR.Editor.SettingsUtil.AOTAssemblyNames;
// 检查两个列表是否都为空,如果是,记录日志并返回。
if (hotUpdateAssemblyFiles.Count == 0 && aotAssemblyNames.Count == 0)
{
Debug.Log("HybridCLR.Editor.SettingsUtil 程序集列表值为空");
return;
}
// 如果列表不为空,则更新相应的设置。
if (hotUpdateAssemblyFiles.Count > 0)
{
SettingsUtils.SetHybridCLRHotUpdateAssemblies(hotUpdateAssemblyFiles);
}
if (aotAssemblyNames.Count > 0)
{
SettingsUtils.SetHybridCLRAOTMetaAssemblies(aotAssemblyNames);
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
Debug.Log("同步AOT和HotUpdate程序集 HybridCLR到TEngineSettings成功。");
}
}

View File

@@ -58,7 +58,7 @@ public class TEngineSettingsProvider : SettingsProvider
m_CustomSettings = GetSerializedSettings();
}
EditorGUILayout.PropertyField(m_CustomSettings.FindProperty("m_BybridCLRCustomGlobalSettings"));
EditorGUILayout.PropertyField(m_CustomSettings.FindProperty("m_HybridCLRCustomGlobalSettings"));
EditorGUILayout.Space(20);
if (!changeCheckScope.changed)
{

View File

@@ -1,5 +1,7 @@
#if ENABLE_HYBRIDCLR
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
#endif
using TEngine.Editor;
using UnityEditor;
using UnityEngine;
@@ -15,6 +17,8 @@ public static class BuildDLLCommand
public static void Disable()
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
HybridCLR.Editor.SettingsUtil.Enable = false;
SyncAssemblyContent.RefreshAssembly();
}
/// <summary>
@@ -25,20 +29,26 @@ public static class BuildDLLCommand
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
ScriptingDefineSymbols.AddScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
HybridCLR.Editor.SettingsUtil.Enable = true;
SyncAssemblyContent.RefreshAssembly();
}
[MenuItem("HybridCLR/Build/BuildAssets And CopyTo AssemblyTextAssetPath")]
public static void BuildAndCopyDlls()
{
#if ENABLE_HYBRIDCLR
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
CompileDllCommand.CompileDll(target);
CopyAOTHotUpdateDlls(target);
#endif
}
public static void BuildAndCopyDlls(BuildTarget target)
{
#if ENABLE_HYBRIDCLR
CompileDllCommand.CompileDll(target);
CopyAOTHotUpdateDlls(target);
#endif
}
public static void CopyAOTHotUpdateDlls(BuildTarget target)
@@ -50,6 +60,7 @@ public static class BuildDLLCommand
public static void CopyAOTAssembliesToAssetPath()
{
#if ENABLE_HYBRIDCLR
var target = EditorUserBuildSettings.activeBuildTarget;
string aotAssembliesSrcDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
string aotAssembliesDstDir = Application.dataPath +"/"+ SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath;
@@ -66,10 +77,12 @@ public static class BuildDLLCommand
System.IO.File.Copy(srcDllPath, dllBytesPath, true);
Debug.Log($"[CopyAOTAssembliesToStreamingAssets] copy AOT dll {srcDllPath} -> {dllBytesPath}");
}
#endif
}
public static void CopyHotUpdateAssembliesToAssetPath()
{
#if ENABLE_HYBRIDCLR
var target = EditorUserBuildSettings.activeBuildTarget;
string hotfixDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
@@ -81,5 +94,6 @@ public static class BuildDLLCommand
System.IO.File.Copy(dllPath, dllBytesPath, true);
Debug.Log($"[CopyHotUpdateAssembliesToStreamingAssets] copy hotfix dll {dllPath} -> {dllBytesPath}");
}
#endif
}
}

View File

@@ -1,56 +0,0 @@
using UnityEditor;
namespace TEngine.Editor.Inspector
{
[CustomEditor(typeof(LocalizationModule))]
internal sealed class LocalizationModuleInspector : GameFrameworkInspector
{
private HelperInfo<LocalizationHelperBase> m_LocalizationHelperInfo = new HelperInfo<LocalizationHelperBase>("Localization");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
LocalizationModule t = (LocalizationModule)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
m_LocalizationHelperInfo.Draw();
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Language", t.Language.ToString());
EditorGUILayout.LabelField("System Language", t.SystemLanguage.ToString());
EditorGUILayout.LabelField("Dictionary Count", t.DictionaryCount.ToString());
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_LocalizationHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_LocalizationHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8c8de00f4cb14c4fa7b28015f55cd5ee
timeCreated: 1695200030

View File

@@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using YooAsset.Editor;
namespace TEngine.Editor.Inspector
{
@@ -18,6 +13,7 @@ namespace TEngine.Editor.Inspector
"HostPlayMode (联机运行模式)",
"WebPlayMode (WebGL运行模式)"
};
private static readonly string[] _verifyLevelNames = new string[]
{
"Low (验证文件存在)",
@@ -25,48 +21,23 @@ namespace TEngine.Editor.Inspector
"High (验证文件大小和CRC)"
};
private SerializedProperty m_PackageName = null;
private SerializedProperty m_PlayMode = null;
private SerializedProperty m_ReadWritePathType = null;
private SerializedProperty m_UpdatableWhilePlaying = null;
private SerializedProperty m_VerifyLevel = null;
private SerializedProperty m_Milliseconds = null;
private SerializedProperty m_ReadWritePathType = null;
private SerializedProperty m_MinUnloadUnusedAssetsInterval = null;
private SerializedProperty m_MaxUnloadUnusedAssetsInterval = null;
private SerializedProperty m_AssetAutoReleaseInterval = null;
private SerializedProperty m_AssetCapacity = null;
private SerializedProperty m_AssetExpireTime = null;
private SerializedProperty m_AssetPriority = null;
private SerializedProperty m_DownloadingMaxNum = null;
private SerializedProperty m_FailedTryAgain = null;
private SerializedProperty m_adaptiveReplacementCacheCapacity = null;
private int m_ResourceModeIndex = 0;
private int m_PackageIndex = 0;
private int m_VerifyIndex = 0;
private PopupField<string> _buildPackageField;
private List<string> _buildPackageNames;
private void OnEnable()
{
m_PackageName = serializedObject.FindProperty("packageName");
m_PlayMode = serializedObject.FindProperty("playMode");
m_VerifyLevel = serializedObject.FindProperty("verifyLevel");
m_Milliseconds = serializedObject.FindProperty("milliseconds");
m_ReadWritePathType = serializedObject.FindProperty("readWritePathType");
m_MinUnloadUnusedAssetsInterval = serializedObject.FindProperty("minUnloadUnusedAssetsInterval");
m_MaxUnloadUnusedAssetsInterval = serializedObject.FindProperty("maxUnloadUnusedAssetsInterval");
m_DownloadingMaxNum = serializedObject.FindProperty("downloadingMaxNum");
m_FailedTryAgain = serializedObject.FindProperty("failedTryAgain");
m_adaptiveReplacementCacheCapacity = serializedObject.FindProperty("adaptiveReplacementCacheCapacity");
RefreshModes();
RefreshTypeNames();
}
private void RefreshModes()
{
m_ResourceModeIndex = m_PlayMode.enumValueIndex > 0 ? m_PlayMode.enumValueIndex : 0;
m_VerifyIndex = m_VerifyLevel.enumValueIndex > 0 ? m_VerifyLevel.enumValueIndex : 0;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
@@ -81,17 +52,10 @@ namespace TEngine.Editor.Inspector
{
EditorGUILayout.EnumPopup("Resource Mode", t.PlayMode);
EditorGUILayout.EnumPopup("VerifyLevel", t.verifyLevel);
_buildPackageNames = GetBuildPackageNames();
if (_buildPackageNames.Count > 0)
{
GUILayout.Label(_buildPackageNames[0]);
}
EditorGUILayout.EnumPopup("VerifyLevel", t.VerifyLevel);
}
else
{
// 资源模式
int selectedIndex = EditorGUILayout.Popup("Resource Mode", m_ResourceModeIndex, _resourceModeNames);
if (selectedIndex != m_ResourceModeIndex)
{
@@ -105,36 +69,12 @@ namespace TEngine.Editor.Inspector
m_VerifyIndex = selectedVerifyIndex;
m_VerifyLevel.enumValueIndex = selectedVerifyIndex;
}
// 包裹名称列表
_buildPackageNames = GetBuildPackageNames();
if (_buildPackageNames.Count > 0)
{
int selectedPackageIndex = EditorGUILayout.Popup("Used Packages", m_PackageIndex, _buildPackageNames.ToArray());
if (selectedPackageIndex != m_PackageIndex)
{
m_PackageIndex = selectedPackageIndex;
m_PlayMode.enumValueIndex = selectedIndex + 1;
}
int defaultIndex = GetDefaultPackageIndex(AssetBundleBuilderSettingData.Setting.BuildPackage);
_buildPackageField = new PopupField<string>(_buildPackageNames, defaultIndex);
_buildPackageField.label = "Build Package";
_buildPackageField.style.width = 350;
_buildPackageField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageField.value;
});
}
else
{
GUILayout.Label("Please Create Packages with YooAssets ...!");
}
}
m_ReadWritePathType.enumValueIndex = (int)(ReadWritePathType)EditorGUILayout.EnumPopup("Read-Write Path Type", t.ReadWritePathType);
}
EditorGUILayout.PropertyField(m_UpdatableWhilePlaying);
EditorGUI.EndDisabledGroup();
int milliseconds = EditorGUILayout.DelayedIntField("Milliseconds", m_Milliseconds.intValue);
@@ -142,7 +82,7 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.milliseconds = milliseconds;
t.Milliseconds = milliseconds;
}
else
{
@@ -150,8 +90,9 @@ namespace TEngine.Editor.Inspector
}
}
float minUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Min Unload Unused Assets Interval", m_MinUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (Math.Abs(minUnloadUnusedAssetsInterval - m_MinUnloadUnusedAssetsInterval.floatValue) > 0.001f)
float minUnloadUnusedAssetsInterval =
EditorGUILayout.Slider("Min Unload Unused Assets Interval", m_MinUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (Math.Abs(minUnloadUnusedAssetsInterval - m_MinUnloadUnusedAssetsInterval.floatValue) > 0.01f)
{
if (EditorApplication.isPlaying)
{
@@ -163,8 +104,9 @@ namespace TEngine.Editor.Inspector
}
}
float maxUnloadUnusedAssetsInterval = EditorGUILayout.Slider("Max Unload Unused Assets Interval", m_MaxUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (Math.Abs(maxUnloadUnusedAssetsInterval - m_MaxUnloadUnusedAssetsInterval.floatValue) > 0.001f)
float maxUnloadUnusedAssetsInterval =
EditorGUILayout.Slider("Max Unload Unused Assets Interval", m_MaxUnloadUnusedAssetsInterval.floatValue, 0f, 3600f);
if (Math.Abs(maxUnloadUnusedAssetsInterval - m_MaxUnloadUnusedAssetsInterval.floatValue) > 0.01f)
{
if (EditorApplication.isPlaying)
{
@@ -181,7 +123,7 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.downloadingMaxNum = (int)downloadingMaxNum;
t.DownloadingMaxNum = (int)downloadingMaxNum;
}
else
{
@@ -194,7 +136,7 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.failedTryAgain = (int)failedTryAgain;
t.FailedTryAgain = (int)failedTryAgain;
}
else
{
@@ -202,28 +144,69 @@ namespace TEngine.Editor.Inspector
}
}
int adaptiveReplacementCacheCapacity = (int)EditorGUILayout.Slider("ARC Table Capacity", m_adaptiveReplacementCacheCapacity.intValue, 8f, 128f);
if (adaptiveReplacementCacheCapacity != m_adaptiveReplacementCacheCapacity.intValue)
EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
{
float assetAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Asset Auto Release Interval", m_AssetAutoReleaseInterval.floatValue);
if (Math.Abs(assetAutoReleaseInterval - m_AssetAutoReleaseInterval.floatValue) > 0.01f)
{
if (EditorApplication.isPlaying)
{
t.adaptiveReplacementCacheCapacity = adaptiveReplacementCacheCapacity;
t.AssetAutoReleaseInterval = assetAutoReleaseInterval;
}
else
{
m_adaptiveReplacementCacheCapacity.intValue = adaptiveReplacementCacheCapacity;
m_AssetAutoReleaseInterval.floatValue = assetAutoReleaseInterval;
}
}
int assetCapacity = EditorGUILayout.DelayedIntField("Asset Capacity", m_AssetCapacity.intValue);
if (assetCapacity != m_AssetCapacity.intValue)
{
if (EditorApplication.isPlaying)
{
t.AssetCapacity = assetCapacity;
}
else
{
m_AssetCapacity.intValue = assetCapacity;
}
}
float assetExpireTime = EditorGUILayout.DelayedFloatField("Asset Expire Time", m_AssetExpireTime.floatValue);
if (Math.Abs(assetExpireTime - m_AssetExpireTime.floatValue) > 0.01f)
{
if (EditorApplication.isPlaying)
{
t.AssetExpireTime = assetExpireTime;
}
else
{
m_AssetExpireTime.floatValue = assetExpireTime;
}
}
int assetPriority = EditorGUILayout.DelayedIntField("Asset Priority", m_AssetPriority.intValue);
if (assetPriority != m_AssetPriority.intValue)
{
if (EditorApplication.isPlaying)
{
t.AssetPriority = assetPriority;
}
else
{
m_AssetPriority.intValue = assetPriority;
}
}
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Unload Unused Assets",
Utility.Text.Format("{0:F2} / {1:F2}", t.LastUnloadUnusedAssetsOperationElapseSeconds, t.MaxUnloadUnusedAssetsInterval));
EditorGUILayout.LabelField("Read-Only Path", t.ReadOnlyPath.ToString());
EditorGUILayout.LabelField("Read-Write Path", t.ReadWritePath.ToString());
EditorGUILayout.LabelField("Read-Only Path", t?.ReadOnlyPath?.ToString());
EditorGUILayout.LabelField("Read-Write Path", t?.ReadWritePath?.ToString());
EditorGUILayout.LabelField("Applicable Game Version", t.ApplicableGameVersion ?? "<Unknwon>");
EditorGUILayout.LabelField("Internal Resource Version", t.InternalResourceVersion.ToString());
}
serializedObject.ApplyModifiedProperties();
@@ -238,36 +221,35 @@ namespace TEngine.Editor.Inspector
RefreshTypeNames();
}
private void OnEnable()
{
m_PlayMode = serializedObject.FindProperty("playMode");
m_UpdatableWhilePlaying = serializedObject.FindProperty("m_UpdatableWhilePlaying");
m_VerifyLevel = serializedObject.FindProperty("VerifyLevel");
m_Milliseconds = serializedObject.FindProperty("Milliseconds");
m_ReadWritePathType = serializedObject.FindProperty("m_ReadWritePathType");
m_MinUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MinUnloadUnusedAssetsInterval");
m_MaxUnloadUnusedAssetsInterval = serializedObject.FindProperty("m_MaxUnloadUnusedAssetsInterval");
m_AssetAutoReleaseInterval = serializedObject.FindProperty("m_AssetAutoReleaseInterval");
m_AssetCapacity = serializedObject.FindProperty("m_AssetCapacity");
m_AssetExpireTime = serializedObject.FindProperty("m_AssetExpireTime");
m_AssetPriority = serializedObject.FindProperty("m_AssetPriority");
m_DownloadingMaxNum = serializedObject.FindProperty("m_DownloadingMaxNum");
m_FailedTryAgain = serializedObject.FindProperty("m_FailedTryAgain");
RefreshModes();
RefreshTypeNames();
}
private void RefreshModes()
{
m_ResourceModeIndex = m_PlayMode.enumValueIndex > 0 ? m_PlayMode.enumValueIndex : 0;
m_VerifyIndex = m_VerifyLevel.enumValueIndex > 0 ? m_VerifyLevel.enumValueIndex : 0;
}
private void RefreshTypeNames()
{
serializedObject.ApplyModifiedProperties();
}
// 构建包裹相关
private int GetDefaultPackageIndex(string packageName)
{
for (int index = 0; index < _buildPackageNames.Count; index++)
{
if (_buildPackageNames[index] == packageName)
{
return index;
}
}
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageNames[0];
return 0;
}
private List<string> GetBuildPackageNames()
{
List<string> result = new List<string>();
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
{
result.Add(package.PackageName);
}
return result;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 6a824de3af698c34bb4343dbb911498b
guid: eee776b99f3e76a4c968d6943979829b
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,763 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace TEngine.Localization
{
public class GUITools
{
static public Color White = Color.white;
static public Color LightGray = Color.Lerp(Color.gray, Color.white, 0.5f);
static public Color DarkGray = Color.Lerp(Color.gray, Color.white, 0.2f);
static public Color LightYellow = Color.Lerp(Color.yellow, Color.white, 0.5f);
static public GUILayoutOption DontExpandWidth = GUILayout.ExpandWidth(false);
static public GUIContent EmptyContent = new GUIContent ();
static List<System.Action> mDelayedEditorCallbacks = new List<System.Action>();
#region Delayed Editor Callback
public static void DelayedCall( System.Action action )
{
if (mDelayedEditorCallbacks.Count == 0)
EditorApplication.update += OnDelayedCall;
mDelayedEditorCallbacks.Add(action);
}
static void OnDelayedCall()
{
EditorApplication.update -= OnDelayedCall;
var calls = mDelayedEditorCallbacks.ToArray();
mDelayedEditorCallbacks.Clear();
foreach (var call in calls)
call();
}
#endregion
#region Header
public delegate void fnOnToggled(bool enabled);
static public bool DrawHeader (string text, string key, bool ShowToggle=false, bool ToggleState=false, fnOnToggled OnToggle = null, string HelpURL=default(string), Color disabledColor = default(Color))
{
bool state = EditorPrefs.GetBool(key, false);
bool newState = DrawHeader (text, state, ShowToggle, ToggleState, OnToggle, HelpURL, disabledColor);
if (state!=newState) EditorPrefs.SetBool(key, newState);
return newState;
}
static public bool DrawHeader (string text, bool state, bool ShowToggle=false, bool ToggleState=false, fnOnToggled OnToggle = null, string HelpURL=default(string), Color disabledColor = default(Color), bool allowCollapsing = true)
{
GUIStyle Style = new GUIStyle(EditorStyles.foldout);
Style.richText = true;
EditorStyles.foldout.richText = true;
if (state)
{
//GUI.backgroundColor=DarkGray;
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea/*, GUILayout.Height(1)*/);
GUILayout.BeginHorizontal();
if (!string.IsNullOrEmpty(text))
{
if (allowCollapsing)
state = GUILayout.Toggle(state, text, Style, GUILayout.ExpandWidth(true));
else
GUILayout.Label(text, GUILayout.ExpandWidth(true));
}
if (!string.IsNullOrEmpty(HelpURL))
{
if (GUILayout.Button (Icon_Help, EditorStyles.label, GUILayout.ExpandWidth(false)))
Application.OpenURL(HelpURL);
}
if (ShowToggle)
{
GUI.changed = false;
bool newBool = GUILayout.Toggle(ToggleState, "", "OL Toggle", GUILayout.ExpandWidth(false));
if (GUI.changed && OnToggle!=null)
OnToggle(newBool);
}
GUILayout.EndHorizontal();
GUILayout.Space(2);
//GUI.backgroundColor = Color.white;
}
else
{
if (ShowToggle && !ToggleState)
GUI.color = disabledColor;
GUILayout.BeginHorizontal("Box");
//GUILayout.BeginHorizontal(EditorStyles.toolbar);
state = GUILayout.Toggle(state, text, Style, GUILayout.ExpandWidth(true));
if (ShowToggle)
{
GUI.changed = false;
bool newBool = GUILayout.Toggle(ToggleState, "", "OL Toggle", GUILayout.ExpandWidth(false));
if (GUI.changed && OnToggle!=null)
OnToggle(newBool);
}
GUILayout.EndHorizontal();
GUI.color = White;
}
return state;
}
static public void CloseHeader()
{
GUILayout.EndHorizontal();
}
public static void OnGUI_Footer(string pluginName, string pluginVersion, string helpURL, string documentationURL, string assetStoreURL)
{
GUILayout.BeginHorizontal();
string versionTip = "";
/*if (I2Analytics.HasNewVersion(pluginName))
{
versionTip = "There is a new version of " + pluginName + ".\nClick here for more details";
if (GUILayout.Button(new GUIContent("", versionTip), EditorStyles.label, GUILayout.Width(25)))
I2AboutWindow.DoShowScreen();
var rect = GUILayoutUtility.GetLastRect();
rect.yMin = rect.yMax - 25;
rect.xMax = rect.xMin + 25;
rect.y += 3;
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
}*/
if (GUILayout.Button(new GUIContent("v" + pluginVersion, versionTip), EditorStyles.miniLabel))
{
Application.OpenURL(assetStoreURL);
//I2AboutWindow.DoShowScreen();
}
GUILayout.FlexibleSpace();
if (GUILayout.Button("Ask a Question", EditorStyles.miniLabel))
Application.OpenURL(helpURL);
GUILayout.Space(10);
if (GUILayout.Button("Documentation", EditorStyles.miniLabel))
Application.OpenURL(documentationURL);
GUILayout.EndHorizontal();
}
#endregion
#region Content
static public void BeginContents ()
{
EditorGUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight(10f));
GUILayout.Space(2f);
EditorGUILayout.BeginVertical();
GUILayout.Space(2f);
}
static public void EndContents () { EndContents(true); }
static public void EndContents ( bool closeHeader )
{
GUILayout.Space(2f);
EditorGUILayout.EndVertical();
GUILayout.Space(3f);
GUILayout.EndHorizontal();
if (closeHeader) CloseHeader();
}
#endregion
#region Tabs
static public void DrawTabs( SerializedProperty mProperty, GUIStyle Style=null, int height=25 )
{
int curIndex = mProperty.enumValueIndex;
int newIndex = DrawTabs( curIndex, mProperty.enumNames, Style, height);
if (curIndex!=newIndex)
mProperty.enumValueIndex = newIndex;
}
static public int DrawTabs( int Index, string[] Tabs, GUIStyle Style=null, int height=25, bool expand = true)
{
GUIStyle MyStyle = new GUIStyle(Style!=null?Style:GUI.skin.FindStyle("dragtab"));
MyStyle.fixedHeight=0;
GUILayout.BeginHorizontal();
for (int i=0; i<Tabs.Length; ++i)
{
int idx = Tabs[i].IndexOf('|');
if (idx>0)
{
string text = Tabs[i].Substring(0, idx);
string tooltip = Tabs[i].Substring(idx+1);
if ( GUILayout.Toggle(Index==i, new GUIContent(text, tooltip), MyStyle, GUILayout.Height(height), GUILayout.ExpandWidth(expand)) && Index!=i)
{
Index=i;
GUI.FocusControl(string.Empty);
}
}
else
{
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height), GUILayout.ExpandWidth(expand)) && Index!=i)
{
Index=i;
GUI.FocusControl(string.Empty);
}
}
}
GUILayout.EndHorizontal();
return Index;
}
static public void DrawShadowedTabs( SerializedProperty mProperty, GUIStyle Style=null, int height=25, bool expand=true )
{
int curIndex = mProperty.enumValueIndex;
int newIndex = DrawShadowedTabs( curIndex, mProperty.enumNames, height, expand);
if (curIndex!=newIndex)
mProperty.enumValueIndex = newIndex;
}
static public int DrawShadowedTabs( int Index, string[] Tabs, int height = 25, bool expand=true )
{
GUI.backgroundColor=Color.Lerp (Color.gray, Color.white, 0.2f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
GUI.backgroundColor=Color.white;
GUILayout.Space(2);
Index = DrawTabs( Index, Tabs, height: height, expand:expand );
GUILayout.EndVertical();
return Index;
}
static public int DrawTabs( int Index, Texture2D[] Tabs, GUIStyle Style, int height )
{
GUIStyle MyStyle = new GUIStyle(Style!=null?Style:GUI.skin.FindStyle("dragtab"));
MyStyle.fixedHeight=0;
//width = Mathf.Max (width, height * Tabs[0].width/(float)Tabs[0].height);
GUILayout.BeginHorizontal();
float width = (EditorGUIUtility.currentViewWidth-(MyStyle.border.left+MyStyle.border.right)*(Tabs.Length-1)) / Tabs.Length;
for (int i=0; i<Tabs.Length; ++i)
{
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height), GUILayout.Width(width)) && Index!=i)
{
Index=i;
GUI.changed = true;
}
}
GUILayout.EndHorizontal();
return Index;
}
#endregion
#region Object Array
static public bool DrawObjectsArray( SerializedProperty PropArray, bool allowDuplicates=false, bool allowResources=false, bool allowSceneObj=false, Object testAdd=null, Object testReplace=null, int testReplaceIndex=-1, int testDeleteIndex=-1 )
{
bool hasChanged = false;
GUILayout.BeginVertical();
int DeleteElement = -1, MoveUpElement = -1;
for (int i=0, imax=PropArray.arraySize; i<imax; ++i)
{
SerializedProperty Prop = PropArray.GetArrayElementAtIndex(i);
GUILayout.BeginHorizontal();
//--[ Delete Button ]-------------------
if (GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)) || i == testDeleteIndex)
DeleteElement = i;
GUILayout.Space(2);
//--[ Object ]--------------------------
GUILayout.BeginHorizontal(EditorStyles.toolbar);
GUI.changed = false;
Object Obj = EditorGUILayout.ObjectField( Prop.objectReferenceValue, typeof(Object), allowSceneObj, GUILayout.ExpandWidth(true));
if (testReplaceIndex == i)
{
Obj = testReplace;
GUI.changed = true;
}
if (!allowResources && Obj != null)
{
var path = AssetDatabase.GetAssetPath(Obj);
if (path != null && path.Contains("/Resources/"))
Obj = null;
}
if (Obj==null)
DeleteElement = i;
else
if (GUI.changed && (allowDuplicates || !ObjectsArrayHasReference(PropArray, Obj)))
{
Prop.objectReferenceValue = Obj;
hasChanged = true;
}
GUILayout.EndHorizontal();
//--[ MoveUp Button ]-------------------
if (i==0)
{
if (imax>1)
GUILayout.Space (18);
}
else
{
if (GUILayout.Button( "\u25B2", EditorStyles.toolbarButton, GUILayout.Width(18)))
MoveUpElement = i;
}
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal(EditorStyles.toolbar);
Object NewObj = EditorGUILayout.ObjectField( null, typeof(Object), allowSceneObj, GUILayout.ExpandWidth(true));
if (testAdd != null)
{
NewObj = testAdd;
}
if (!allowResources && NewObj != null)
{
var path = AssetDatabase.GetAssetPath(NewObj);
if (path != null && path.Contains("/Resources/"))
NewObj = null;
}
if (NewObj && (allowDuplicates || !ObjectsArrayHasReference(PropArray, NewObj)))
{
int Index = PropArray.arraySize;
PropArray.InsertArrayElementAtIndex( Index );
PropArray.GetArrayElementAtIndex(Index).objectReferenceValue = NewObj;
hasChanged = true;
}
GUILayout.EndHorizontal();
if (DeleteElement>=0)
{
PropArray.DeleteArrayElementAtIndex( DeleteElement );
//PropArray.DeleteArrayElementAtIndex( DeleteElement );
hasChanged = true;
}
if (MoveUpElement>=0)
{
PropArray.MoveArrayElement(MoveUpElement, MoveUpElement-1);
hasChanged = true;
}
GUILayout.EndVertical();
return hasChanged;
}
static public bool ObjectsArrayHasReference(SerializedProperty PropArray, Object obj)
{
for (int i = 0, imax = PropArray.arraySize; i < imax; ++i)
{
SerializedProperty Prop = PropArray.GetArrayElementAtIndex(i);
if (Prop.objectReferenceValue == obj)
return true;
}
return false;
}
#endregion
#region Toggle
static public int ToggleToolbar( int Index, string[] Options )
{
GUILayout.BeginHorizontal();
for (int i=0; i<Options.Length; ++i)
{
if ( GUILayout.Toggle(Index==i, Options[i], EditorStyles.toolbarButton))
Index=i;
}
GUILayout.EndHorizontal();
return Index;
}
static public void ToggleToolbar( SerializedProperty EnumVar )
{
int index = ToggleToolbar( EnumVar.enumValueIndex, EnumVar.enumNames);
if (EnumVar.enumValueIndex != index)
EnumVar.enumValueIndex = index;
}
#endregion
#region Misc
public static bool ObjectExistInScene( GameObject Obj )
{
return Obj.scene.IsValid() && Obj.scene.isLoaded;
/* //if (Obj.transform.root != Obj.transform)
// continue;
// We are only interested in GameObjects that are visible in the Hierachy panel and are persitent
if ((Obj.hideFlags & (HideFlags.DontSave|HideFlags.HideInHierarchy)) > 0)
return false;
// We are not interested in Prefab, unless they are Prefab Instances
PrefabType pfType = PrefabUtility.GetPrefabType(Obj);
if(pfType == PrefabType.Prefab || pfType == PrefabType.ModelPrefab)
return false;
// If the database contains the object then its not an scene object,
// but the previous test should get rid of them, so I will just comment this
// unless an false positive object is found in the future
//if (AssetDatabase.Contains(Obj))
// return false;
return true;*/
}
public static IEnumerable<GameObject> SceneRoots()
{
var prop = new HierarchyProperty(HierarchyType.GameObjects);
var expanded = new int[0];
while (prop.Next(expanded)) {
yield return prop.pptrValue as GameObject;
}
}
public static List<GameObject> SceneRootsList()
{
return new List<GameObject>(SceneRoots());
}
public static IEnumerable<Transform> AllSceneObjects()
{
var queue = new Queue<Transform>();
foreach (var root in SceneRoots()) {
var tf = root.transform;
yield return tf;
queue.Enqueue(tf);
}
while (queue.Count > 0) {
foreach (Transform child in queue.Dequeue()) {
yield return child;
queue.Enqueue(child);
}
}
}
public static string GetScenePath(Transform tr)
{
if (tr==null)
return string.Empty;
string path = tr.name;
while (tr.parent != null)
{
tr = tr.parent;
path = tr.name + "/" + path;
}
return path;
}
public static Transform FindObjectInEditor( string scenePath )
{
if (string.IsNullOrEmpty(scenePath))
return null;
int index = scenePath.IndexOfAny("/\\".ToCharArray());
string first = index<0 ? scenePath : scenePath.Substring(0, index);
foreach (var root in AllSceneObjects())
if (root.name==first)
{
if (index<0)
return root;
return root.Find(scenePath.Substring(index+1));
}
return null;
}
public static GUIContent Icon_Help {
get{
if (mIconHelp == null)
mIconHelp = EditorGUIUtility.IconContent("_Help");
return mIconHelp;
}
}
static GUIContent mIconHelp;
public static GUIStyle FindSkinStyle(string name)
{
var allStyles = GUI.skin.customStyles;
for (int i = 0, imax = allStyles.Length; i < imax; ++i)
{
if (allStyles[i].name == name)
return allStyles[i];
}
return null;
}
public static void DrawSkinIcon(Rect rect, params string[] iconNames)
{
foreach (var icon in iconNames)
{
var style = FindSkinStyle(icon);
if (style == null || style.normal == null || style.normal.background == null)
continue;
GUI.DrawTexture(rect, style.normal.background);
return;
}
//Debug.Log("unable to find icon");
}
#endregion
#region Angle Drawer
private static Vector2 mAngle_lastMousePosition;
static Texture mAngle_TextureCircle;
static Texture pAngle_TextureCircle {
get{
if (mAngle_TextureCircle) return mAngle_TextureCircle;
mAngle_TextureCircle = GUI.skin.GetStyle("CN CountBadge").normal.background;
return mAngle_TextureCircle;
}
}
public static float FloatAngle(Rect rect, float value)
{
return FloatAngle(rect, value, -1, -1, -1);
}
public static float FloatAngle(Rect rect, float value, float snap)
{
return FloatAngle(rect, value, snap, -1, -1);
}
public static float FloatAngle(Rect rect, float value, float snap, float min, float max)
{
int id = GUIUtility.GetControlID(FocusType.Passive, rect);
Rect knobRect = new Rect(rect.x, rect.y, rect.height, rect.height);
float delta;
if (min != max)
delta = (max - min) / 360;
else
delta = 1;
if (UnityEngine.Event.current != null)
{
if (UnityEngine.Event.current.type == EventType.MouseDown && knobRect.Contains(UnityEngine.Event.current.mousePosition))
{
GUIUtility.hotControl = id;
mAngle_lastMousePosition = UnityEngine.Event.current.mousePosition;
}
else if (UnityEngine.Event.current.type == EventType.MouseUp && GUIUtility.hotControl == id)
GUIUtility.hotControl = -1;
else if (UnityEngine.Event.current.type == EventType.MouseDrag && GUIUtility.hotControl == id)
{
Vector2 move = mAngle_lastMousePosition - UnityEngine.Event.current.mousePosition;
value += delta * (-move.x - move.y);
if (snap > 0)
{
float mod = value % snap;
if (mod < delta * 3 || Mathf.Abs(mod - snap) < delta * 3)
value = Mathf.Round(value / snap) * snap;
}
mAngle_lastMousePosition = UnityEngine.Event.current.mousePosition;
GUI.changed = true;
}
}
if (pAngle_TextureCircle) GUI.DrawTexture(knobRect, pAngle_TextureCircle);
Matrix4x4 matrix = GUI.matrix;
if (min != max)
GUIUtility.RotateAroundPivot(value * (360 / (max - min)), knobRect.center);
else
GUIUtility.RotateAroundPivot(value, knobRect.center);
knobRect.height = 5;
knobRect.width = 5;
if (pAngle_TextureCircle) GUI.DrawTexture(knobRect, pAngle_TextureCircle);
GUI.matrix = matrix;
Rect label = new Rect(rect.x + rect.height, rect.y + rect.height / 2 - 9, rect.height, 18);
value = EditorGUI.FloatField(label, value);
if (min != max)
value = Mathf.Clamp(value, min, max);
return value;
}
public static float AngleCircle(Rect rect, float angle, float snap, float min, float max, Texture background=null, Texture knobLine=null)
{
Rect knobRect = new Rect(rect.x, rect.y, rect.height, rect.height);
float delta;
if (min != max)
delta = (max - min) / 360;
else
delta = 1;
if (UnityEngine.Event.current != null && GUIUtility.hotControl<=0 && (UnityEngine.Event.current.type==EventType.MouseDown || UnityEngine.Event.current.type==EventType.MouseDrag) && knobRect.Contains(UnityEngine.Event.current.mousePosition))
{
angle = Vector2.Angle( Vector2.right, UnityEngine.Event.current.mousePosition-knobRect.center);
if (UnityEngine.Event.current.mousePosition.y<knobRect.center.y) angle = 360-angle;
if (UnityEngine.Event.current.alt || UnityEngine.Event.current.control)
snap = 5;
if (snap > 0)
{
float mod = Mathf.Repeat(angle, snap);
if (mod < delta * 3 || Mathf.Abs(mod - snap) < delta * 3)
angle = Mathf.Round(angle / snap) * snap;
}
GUI.changed = true;
}
if (background==null) background = pAngle_TextureCircle;
if (background) GUI.DrawTexture (knobRect, background);
Matrix4x4 matrix = GUI.matrix;
if (min != max)
GUIUtility.RotateAroundPivot(angle * (360 / (max - min))+90, knobRect.center);
else
GUIUtility.RotateAroundPivot(angle+90, knobRect.center);
float Radius = Mathf.Min (knobRect.width, knobRect.height) * 0.5f;
knobRect.x = knobRect.x + 0.5f * knobRect.width - 4;
knobRect.y += 2;
knobRect.width = 8;
knobRect.height = Radius+2;
if (knobLine == null)
knobLine = GUI.skin.FindStyle ("MeBlendPosition").normal.background;
if (knobLine) GUI.DrawTexture(knobRect, knobLine);
GUI.matrix = matrix;
return Mathf.Repeat(angle, 360);
}
#endregion
#region Unity Version branching
public static string Editor_GetCurrentScene()
{
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
return EditorApplication.currentScene;
#else
return SceneManager.GetActiveScene().path;
#endif
}
public static void Editor_MarkSceneDirty()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
#else
EditorApplication.MarkSceneDirty();
#endif
}
public static void Editor_SaveScene()
{
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
EditorApplication.SaveScene ();
#else
EditorSceneManager.SaveOpenScenes();
#endif
}
public static void Editor_OpenScene( string sceneName )
{
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
EditorApplication.OpenScene( sceneName );
#else
EditorSceneManager.OpenScene(sceneName);
#endif
}
#endregion
#region Reflection
static public object Reflection_InvokeMethod ( object instanceObject, string methodName, params object[] p_args )
{
BindingFlags _flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
MethodInfo mi = instanceObject.GetType().GetMethods( _flags ).Where( x => x.Name==methodName ).FirstOrDefault();
if (mi == null) return null;
return mi.Invoke( instanceObject, p_args );
}
static public object Reflection_InvokeMethod ( Type targetType, string methodName, params object[] p_args )
{
BindingFlags _flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
MethodInfo mi = targetType.GetMethods( _flags ).Where( x => x.Name==methodName ).FirstOrDefault();
if (mi == null) return null;
return mi.Invoke( null, p_args );
}
public static object s_RecycledEditor;
public static string TextField ( Rect position, string text, int maxLength, GUIStyle style, int controlID )
{
if (s_RecycledEditor==null)
{
FieldInfo info = typeof(EditorGUI).GetField("s_RecycledEditor", BindingFlags.NonPublic | BindingFlags.Static);
s_RecycledEditor = info.GetValue(null);
}
if (s_RecycledEditor == null)
return "";
return Reflection_InvokeMethod( typeof( EditorGUI ), "DoTextField", s_RecycledEditor, controlID, position, text, style, null, false, false, false, false ) as string;
}
static public void RepaintInspectors()
{
EditorApplication.update -= RepaintInspectors;
var assemblyEditor = Assembly.GetAssembly(typeof(UnityEditor.Editor));
var typeInspectorWindow = assemblyEditor.GetType("UnityEditor.InspectorWindow");
typeInspectorWindow.GetMethod("RepaintAllInspectors", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);
}
public static void ScheduleRepaintInspectors()
{
EditorApplication.update += RepaintInspectors;
}
#endregion
#if UNITY_2022_3_OR_NEWER
public const string Style_ToolbarSearchTextField = "ToolbarSearchTextField";
public const string Style_ToolbarSearchCancelButtonEmpty = "ToolbarSearchCancelButtonEmpty";
public const string Style_ToolbarSearchCancelButton = "ToolbarSearchCancelButton";
#else
public const string Style_ToolbarSearchTextField = "ToolbarSeachTextField";
public const string Style_ToolbarSearchCancelButtonEmpty = "ToolbarSeachCancelButtonEmpty";
public const string Style_ToolbarSearchCancelButton = "ToolbarSeachCancelButton";
#endif
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: df33c1000ac895241a433812e40a2096
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a500716e59f61824ba1fa6b418ce31a7
folderAsset: yes
timeCreated: 1461137613
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using UnityEditor;
namespace TEngine.Localization
{
[CustomEditor(typeof(LanguageSourceAsset))]
public class LanguageSourceAssetInspector : LocalizationEditor
{
void OnEnable()
{
var newSource = target as LanguageSourceAsset;
SerializedProperty propSource = serializedObject.FindProperty("mSource");
Custom_OnEnable(newSource.mSource, propSource);
}
public override LanguageSourceData GetSourceData()
{
return (target as LanguageSourceAsset).mSource;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f03a75bf70a306a4fb36646f24c1c1f1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using UnityEditor;
namespace TEngine.Localization
{
[CustomEditor(typeof(LanguageSource))]
public class LanguageSourceInspector : LocalizationEditor
{
void OnEnable()
{
var newSource = target as LanguageSource;
SerializedProperty propSource = serializedObject.FindProperty("mSource");
Custom_OnEnable(newSource.mSource, propSource);
}
public override LanguageSourceData GetSourceData()
{
return (target as LanguageSource).mSource;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a441ed994a43a0a4a9d33be67a8d3f15
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,200 @@
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public abstract partial class LocalizationEditor : UnityEditor.Editor
{
#region Variables
SerializedProperty mProp_Assets, mProp_Languages,
mProp_Google_WebServiceURL, mProp_GoogleUpdateFrequency, mProp_GoogleUpdateDelay, mProp_Google_SpreadsheetKey, mProp_Google_SpreadsheetName, mProp_Google_Password,
mProp_Spreadsheet_LocalFileName, mProp_Spreadsheet_LocalCSVSeparator, mProp_CaseInsensitiveTerms, mProp_Spreadsheet_LocalCSVEncoding,
mProp_OnMissingTranslation, mProp_AppNameTerm, mProp_IgnoreDeviceLanguage, mProp_Spreadsheet_SpecializationAsRows, mProp_Spreadsheet_SortRows, mProp_GoogleInEditorCheckFrequency,
mProp_HighlightLocalizedTargets, mProp_GoogleLiveSyncIsUptoDate, mProp_AllowUnloadingLanguages, mProp_GoogleUpdateSynchronization;
public static LanguageSourceData mLanguageSource;
public static Object mLanguageSourceObject;
public static LocalizationEditor mLanguageSourceEditor;
public static UnityEditor.Editor mCurrentInspector;
static bool mIsParsing; // This is true when the editor is opening several scenes to avoid reparsing objects
#endregion
#region Variables GUI
GUIStyle Style_ToolBar_Big, Style_ToolBarButton_Big;
public GUISkin CustomSkin;
static Vector3 mScrollPos_Languages;
public static string mLanguages_NewLanguage = "";
#endregion
#region Styles
public static GUIStyle Style_WrapTextField {
get{
if (mStyle_WrapTextField==null)
{
mStyle_WrapTextField = new GUIStyle(EditorStyles.textArea);
mStyle_WrapTextField.wordWrap = true;
mStyle_WrapTextField.fixedHeight = 0;
}
return mStyle_WrapTextField;
}
}
static GUIStyle mStyle_WrapTextField;
#endregion
#region Inspector
public void Custom_OnEnable( LanguageSourceData sourceData, SerializedProperty propSource)
{
bool ForceParse = mLanguageSource != sourceData;
mLanguageSource = sourceData;
mLanguageSourceEditor = this;
mCurrentInspector = this;
if (!LocalizationManager.Sources.Contains(mLanguageSource))
LocalizationManager.UpdateSources();
mProp_Assets = propSource.FindPropertyRelative("Assets");
mProp_Languages = propSource.FindPropertyRelative("mLanguages");
mProp_Google_WebServiceURL = propSource.FindPropertyRelative("Google_WebServiceURL");
mProp_GoogleUpdateFrequency = propSource.FindPropertyRelative("GoogleUpdateFrequency");
mProp_GoogleUpdateSynchronization = propSource.FindPropertyRelative("GoogleUpdateSynchronization");
mProp_GoogleInEditorCheckFrequency = propSource.FindPropertyRelative("GoogleInEditorCheckFrequency");
mProp_GoogleUpdateDelay = propSource.FindPropertyRelative("GoogleUpdateDelay");
mProp_Google_SpreadsheetKey = propSource.FindPropertyRelative("Google_SpreadsheetKey");
mProp_Google_SpreadsheetName = propSource.FindPropertyRelative("Google_SpreadsheetName");
mProp_Google_Password = propSource.FindPropertyRelative("Google_Password");
mProp_CaseInsensitiveTerms = propSource.FindPropertyRelative("CaseInsensitiveTerms");
mProp_Spreadsheet_LocalFileName = propSource.FindPropertyRelative("Spreadsheet_LocalFileName");
mProp_Spreadsheet_LocalCSVSeparator = propSource.FindPropertyRelative("Spreadsheet_LocalCSVSeparator");
mProp_Spreadsheet_LocalCSVEncoding = propSource.FindPropertyRelative("Spreadsheet_LocalCSVEncoding");
mProp_Spreadsheet_SpecializationAsRows = propSource.FindPropertyRelative("Spreadsheet_SpecializationAsRows");
mProp_Spreadsheet_SortRows = propSource.FindPropertyRelative("Spreadsheet_SortRows");
mProp_OnMissingTranslation = propSource.FindPropertyRelative("OnMissingTranslation");
mProp_AppNameTerm = propSource.FindPropertyRelative("mTerm_AppName");
mProp_IgnoreDeviceLanguage = propSource.FindPropertyRelative("IgnoreDeviceLanguage");
mProp_GoogleLiveSyncIsUptoDate = propSource.FindPropertyRelative("GoogleLiveSyncIsUptoDate");
mProp_AllowUnloadingLanguages = propSource.FindPropertyRelative("_AllowUnloadingLanguages");
if (!mIsParsing)
{
if (string.IsNullOrEmpty(mLanguageSource.Google_SpreadsheetKey))
mSpreadsheetMode = eSpreadsheetMode.Local;
else
mSpreadsheetMode = eSpreadsheetMode.Google;
mCurrentViewMode = mLanguageSource.mLanguages.Count>0 ? eViewMode.Keys : eViewMode.Languages;
UpdateSelectedKeys();
if (ForceParse || mParsedTerms.Count < mLanguageSource.mTerms.Count)
{
mSelectedCategories.Clear();
ParseTerms(true, false, true);
}
}
ScheduleUpdateTermsToShowInList();
LoadSelectedCategories();
//UpgradeManager.EnablePlugins();
}
void OnDisable()
{
//LocalizationManager.LocalizeAll();
SaveSelectedCategories();
mLanguageSourceEditor = null;
if (mCurrentInspector==this) mCurrentInspector = null;
}
void UpdateSelectedKeys()
{
// Remove all keys that are not in this source
string trans;
for (int i=mSelectedKeys.Count-1; i>=0; --i)
if (!mLanguageSource.TryGetTranslation(mSelectedKeys[i], out trans))
mSelectedKeys.RemoveAt(i);
// Remove all Categories that are not in this source
/*var mCateg = mLanguageSource.GetCategories();
for (int i=mSelectedCategories.Count-1; i>=0; --i)
if (!mCateg.Contains(mSelectedCategories[i]))
mSelectedCategories.RemoveAt(i);
if (mSelectedCategories.Count==0)
mSelectedCategories = mCateg;*/
if (mSelectedScenes.Count==0)
mSelectedScenes.Add (Editor_GetCurrentScene());
}
public override void OnInspectorGUI()
{
// Load Test:
/*if (mLanguageSource.mTerms.Count<40000)
{
mLanguageSource.mTerms.Clear();
for (int i=0; i<40020; ++i)
mLanguageSource.AddTerm("ahh"+i.ToString("00000"), eTermType.Text, false);
mLanguageSource.UpdateDictionary();
}*/
//Profiler.maxNumberOfSamplesPerFrame = -1; // REMOVE ---------------------------------------------------
mIsParsing = false;
//#if UNITY_5_6_OR_NEWER
// serializedObject.UpdateIfRequiredOrScript();
//#else
// serializedObject.UpdateIfDirtyOrScript();
//#endif
if (mLanguageSource.mTerms.Count<1000)
Undo.RecordObject(target, "LanguageSource");
//GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
//GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
//GUI.backgroundColor = Color.white;
if (GUILayout.Button("Language Source", LocalizeInspector.GUIStyle_Header))
{
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
}
InitializeStyles();
GUILayout.Space(10);
//GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
//GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
//GUI.backgroundColor = Color.white;
OnGUI_Main();
//GUILayout.EndVertical();
GUILayout.Space (10);
GUILayout.FlexibleSpace();
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), LocalizeInspector.HelpURL_forum, LocalizeInspector.HelpURL_Documentation, LocalizeInspector.HelpURL_AssetStore);
//GUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
if (UnityEngine.Event.current.type == EventType.Repaint)
{
mTestAction = eTest_ActionType.None;
mTestActionArg = null;
mTestActionArg2 = null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 90c932abd0dc445448366dfe101408ba
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace TEngine.Localization
{
[CustomEditor(typeof(LocalizationParamsManager))]
public class LocalizationParamsManagerInspector : UnityEditor.Editor
{
private ReorderableList mList;
private SerializedProperty mProp_IsGlobalManager;
private ReorderableList getList(SerializedObject serObject)
{
if (mList == null) {
mList = new ReorderableList (serObject, serObject.FindProperty ("_Params"), true, true, true, true);
mList.drawElementCallback = drawElementCallback;
mList.drawHeaderCallback = drawHeaderCallback;
mList.onAddCallback = addElementCallback;
mList.onRemoveCallback = removeElementCallback;
}
else
{
mList.serializedProperty = serObject.FindProperty ("_Params");
}
return mList;
}
private void addElementCallback( ReorderableList list )
{
serializedObject.ApplyModifiedProperties();
var objParams = target as LocalizationParamsManager;
objParams._Params.Add(new LocalizationParamsManager.ParamValue());
list.index = objParams._Params.Count - 1;
serializedObject.Update();
}
private void removeElementCallback( ReorderableList list )
{
if (list.index < 0)
return;
serializedObject.ApplyModifiedProperties();
var objParams = target as LocalizationParamsManager;
objParams._Params.RemoveAt(list.index);
serializedObject.Update();
}
private void drawHeaderCallback(Rect rect)
{
GUI.Label(rect, "Parameters:");
}
private void drawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
{
var serializedElement = mList.serializedProperty.GetArrayElementAtIndex (index);
var content = new GUIContent ();
Rect r = rect; r.xMax = r.xMin+40;
GUI.Label(r, "Name");
r = rect; r.xMax = (r.xMax + r.xMin)/2 - 2; r.xMin = r.xMin+40;
EditorGUI.PropertyField (r, serializedElement.FindPropertyRelative ("Name"),content);
r = rect; r.xMin = (r.xMax + r.xMin) / 2 + 2; r.xMax = r.xMin+40;
GUI.Label(r, "Value");
r = rect; r.xMin = (r.xMax + r.xMin)/2 + 2 + 40;
EditorGUI.PropertyField (r, serializedElement.FindPropertyRelative ("Value"), content);
}
void OnEnable()
{
mList = getList(serializedObject);
mProp_IsGlobalManager = serializedObject.FindProperty("_IsGlobalManager");
}
public override void OnInspectorGUI()
{
#if UNITY_5_6_OR_NEWER
serializedObject.UpdateIfRequiredOrScript();
#else
serializedObject.UpdateIfDirtyOrScript();
#endif
GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
GUI.backgroundColor = Color.white;
if (GUILayout.Button("Dynamic Parameters", LocalizeInspector.GUIStyle_Header))
{
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
}
GUILayout.Space(5);
mProp_IsGlobalManager.boolValue = EditorGUILayout.Popup(new GUIContent("Manager Type", "Local Manager only apply parameters to the Localize component in the same GameObject\n\nGlobal Manager apply parameters to all Localize components"), mProp_IsGlobalManager.boolValue ? 1 : 0, new[] { new GUIContent("Local"), new GUIContent("Global") }) == 1;
GUILayout.Space(5);
mList.DoLayoutList();
//EditorGUILayout.PropertyField(serializedObject.FindProperty("_AutoRegister"), new GUIContent("Auto Register"));
GUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 93f1f9aecf6f7ed40ad1a082c22c47e5
timeCreated: 1468111539
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace TEngine.Localization
{
#if !UNITY_5_0 && !UNITY_5_1
[CustomEditor(typeof(LocalizeDropdown))]
public class LocalizeDropdownInspector : UnityEditor.Editor
{
private ReorderableList mList;
private List<string> terms;
private ReorderableList getList(SerializedObject serObject)
{
if (mList == null) {
mList = new ReorderableList (serObject, serObject.FindProperty ("_Terms"), true, true, true, true);
mList.drawElementCallback = drawElementCallback;
mList.drawHeaderCallback = drawHeaderCallback;
mList.onAddCallback = addElementCallback;
mList.onRemoveCallback = removeElementCallback;
}
else
{
mList.serializedProperty = serObject.FindProperty ("_Terms");
}
return mList;
}
private void addElementCallback( ReorderableList list )
{
serializedObject.ApplyModifiedProperties();
var objParams = target as LocalizeDropdown;
objParams._Terms.Add(string.Empty);
list.index = objParams._Terms.Count - 1;
serializedObject.Update();
}
private void removeElementCallback( ReorderableList list )
{
if (list.index < 0)
return;
serializedObject.ApplyModifiedProperties();
var objParams = target as LocalizeDropdown;
objParams._Terms.RemoveAt(list.index);
serializedObject.Update();
}
private void drawHeaderCallback(Rect rect)
{
GUI.Label(rect, "Terms:");
}
private void drawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
{
var serializedElement = mList.serializedProperty.GetArrayElementAtIndex (index);
EditorGUI.BeginChangeCheck ();
var prvIndex = serializedElement.stringValue == "-" || serializedElement.stringValue == "" ? terms.Count - 1 :
serializedElement.stringValue == " " ? terms.Count - 2 :
terms.IndexOf(serializedElement.stringValue);
var newIndex = EditorGUI.Popup(rect, prvIndex, terms.ToArray());
if (EditorGUI.EndChangeCheck ())
{
if (newIndex == terms.Count - 1)
serializedElement.stringValue = "-";
else
if (newIndex < 0 || newIndex == terms.Count - 2)
serializedElement.stringValue = string.Empty;
else
serializedElement.stringValue = terms[newIndex];
}
}
void OnEnable()
{
mList = getList(serializedObject);
}
public override void OnInspectorGUI()
{
#if UNITY_5_6_OR_NEWER
serializedObject.UpdateIfRequiredOrScript();
#else
serializedObject.UpdateIfDirtyOrScript();
#endif
terms = LocalizationManager.GetTermsList ();
terms.Sort(StringComparer.OrdinalIgnoreCase);
terms.Add("");
terms.Add("<inferred from text>");
terms.Add("<none>");
GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_Background);
GUI.backgroundColor = Color.white;
if (GUILayout.Button("Localize DropDown", LocalizeInspector.GUIStyle_Header))
{
Application.OpenURL(LocalizeInspector.HelpURL_Documentation);
}
GUILayout.Space(5);
mList.DoLayoutList();
GUILayout.Space (10);
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), LocalizeInspector.HelpURL_forum, LocalizeInspector.HelpURL_Documentation, LocalizeInspector.HelpURL_AssetStore);
EditorGUIUtility.labelWidth = 0;
GUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
terms = null;
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 65bbef08e6e42d24d9834945c3769202
timeCreated: 1468111539
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,896 @@
//#define UGUI
//#define NGUI
//#define DFGUI
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TEngine.Localization
{
[CustomEditor(typeof(Localize))]
[CanEditMultipleObjects]
public class LocalizeInspector : UnityEditor.Editor
{
#region Variables
Localize mLocalize;
SerializedProperty mProp_mTerm, mProp_mTermSecondary,
mProp_TranslatedObjects, mProp_LocalizeOnAwake, mProp_AlwaysForceLocalize, mProp_AllowLocalizedParameters, mProp_AllowParameters,
mProp_IgnoreRTL, mProp_MaxCharactersInRTL, mProp_CorrectAlignmentForRTL, mProp_IgnoreNumbersInRTL, mProp_TermSuffix, mProp_TermPrefix, mProp_SeparateWords,
mProp_CallbackEvent;
bool mAllowEditKeyName;
string mNewKeyName = "";
string[] mTermsArray;
public static string HelpURL_forum = "http://goo.gl/Uiyu8C";//http://www.inter-illusion.com/forum/i2-localization";
public static string HelpURL_Documentation = "http://www.inter-illusion.com/assets/I2LocalizationManual/I2LocalizationManual.html";
public static string HelpURL_Tutorials = "http://inter-illusion.com/tools/i2-localization";
public static string HelpURL_ReleaseNotes = "http://inter-illusion.com/forum/i2-localization/26-release-notes";
public static string HelpURL_AssetStore = "https://www.assetstore.unity3d.com/#!/content/14884";
public static LocalizeInspector mLocalizeInspector;
#endregion
#region Inspector
void OnEnable()
{
mLocalize = (Localize)target;
mLocalizeInspector = this;
LocalizationEditor.mCurrentInspector = this;
mProp_mTerm = serializedObject.FindProperty("mTerm");
mProp_mTermSecondary = serializedObject.FindProperty("mTermSecondary");
mProp_TranslatedObjects = serializedObject.FindProperty("TranslatedObjects");
mProp_IgnoreRTL = serializedObject.FindProperty("IgnoreRTL");
mProp_SeparateWords = serializedObject.FindProperty("AddSpacesToJoinedLanguages");
mProp_MaxCharactersInRTL = serializedObject.FindProperty ("MaxCharactersInRTL");
mProp_IgnoreNumbersInRTL = serializedObject.FindProperty("IgnoreNumbersInRTL");
mProp_CorrectAlignmentForRTL = serializedObject.FindProperty ("CorrectAlignmentForRTL");
mProp_LocalizeOnAwake = serializedObject.FindProperty("LocalizeOnAwake");
mProp_AlwaysForceLocalize = serializedObject.FindProperty("AlwaysForceLocalize");
mProp_TermSuffix = serializedObject.FindProperty("TermSuffix");
mProp_TermPrefix = serializedObject.FindProperty("TermPrefix");
mProp_CallbackEvent = serializedObject.FindProperty("LocalizeEvent");
mProp_AllowLocalizedParameters = serializedObject.FindProperty("AllowLocalizedParameters");
mProp_AllowParameters = serializedObject.FindProperty("AllowParameters");
if (LocalizationManager.Sources.Count==0)
LocalizationManager.UpdateSources();
//LocalizationEditor.ParseTerms (true);
//mGUI_ShowReferences = (mLocalize.TranslatedObjects!=null && mLocalize.TranslatedObjects.Length>0);
//mGUI_ShowCallback = (mLocalize.LocalizeCallBack.Target!=null);
//mGUI_ShowTems = true;
LocalizationEditor.mKeysDesc_AllowEdit = false;
GUI_SelectedTerm = 0;
mNewKeyName = mLocalize.Term;
if (mLocalize.Source != null)
LocalizationEditor.mLanguageSource = mLocalize.Source.SourceData;
else
{
if (LocalizationManager.Sources.Count==0)
LocalizationManager.UpdateSources();
LocalizationEditor.mLanguageSource = LocalizationManager.GetSourceContaining( mLocalize.Term );
}
//UpgradeManager.EnablePlugins();
LocalizationEditor.ApplyInferredTerm (mLocalize);
RemoveUnusedReferences(mLocalize);
}
void OnDisable()
{
mLocalizeInspector = null;
if (LocalizationEditor.mCurrentInspector == this) LocalizationEditor.mCurrentInspector = null;
if (mLocalize == null)
return;
//#if TextMeshPro
//string previous = null;
//if (!Application.isPlaying && !string.IsNullOrEmpty(mLocalize.TMP_previewLanguage))
//{
// previous = LocalizationManager.CurrentLanguage;
// LocalizationManager.PreviewLanguage( mLocalize.TMP_previewLanguage );
//}
//#endif
//mLocalize.OnLocalize();
// Revert the preview language
// except when in TMPro and not changing to another GameObject (TMPro has a bug where any change causes the inspector to Disable and Enable)
if (!mLocalize.mLocalizeTargetName.Contains("LocalizeTarget_TextMeshPro") || Selection.activeGameObject==null || !Selection.gameObjects.Contains(mLocalize.gameObject))
{
LocalizationManager.LocalizeAll();
}
//#if TextMeshPro
//if (!string.IsNullOrEmpty(previous))
//{
// LocalizationManager.PreviewLanguage(previous);
// mLocalize.TMP_previewLanguage = null;
//}
//#endif
RemoveUnusedReferences(mLocalize);
}
#endregion
#region GUI
public override void OnInspectorGUI()
{
Undo.RecordObject(target, "Localize");
//GUI.backgroundColor = Color.Lerp (Color.black, Color.gray, 1);
//GUILayout.BeginVertical(GUIStyle_Background, GUILayout.Height(1));
//GUI.backgroundColor = Color.white;
if (GUILayout.Button("Localize", GUIStyle_Header))
{
//Application.OpenURL(HelpURL_Documentation);
}
GUILayout.Space(-10);
LocalizationManager.UpdateSources();
if (LocalizationManager.Sources.Count==0)
{
EditorGUILayout.HelpBox("Unable to find a Language Source.", MessageType.Warning);
}
else
{
GUILayout.Space(10);
OnGUI_Target ();
GUILayout.Space(10);
OnGUI_Terms();
//if (mGUI_ShowTems || mGUI_ShowReferences) GUILayout.Space(5);
OnGUI_References();
if (mLocalize.mGUI_ShowReferences || mLocalize.mGUI_ShowCallback) GUILayout.Space(10);
//Localize loc = target as Localize;
//--[ Localize Callback ]----------------------
EditorGUILayout.PropertyField(mProp_CallbackEvent, new GUIContent("On Localize Callback"));
//string HeaderTitle = "On Localize Call:";
//if (!mLocalize.mGUI_ShowCallback && loc.LocalizeCallBack.Target!=null && !string.IsNullOrEmpty(loc.LocalizeCallBack.MethodName))
// HeaderTitle = string.Concat(HeaderTitle, " <b>",loc.LocalizeCallBack.Target.name, ".</b><i>", loc.LocalizeCallBack.MethodName, "</i>");
//mLocalize.mGUI_ShowCallback = GUITools.DrawHeader(HeaderTitle, mLocalize.mGUI_ShowCallback);
//if (mLocalize.mGUI_ShowCallback)
//{
// GUITools.BeginContents();
// DrawEventCallBack( loc.LocalizeCallBack, loc );
// GUITools.EndContents();
//}
}
OnGUI_Source ();
GUILayout.Space (10);
GUITools.OnGUI_Footer("I2 Localization", LocalizationManager.GetVersion(), HelpURL_forum, HelpURL_Documentation, HelpURL_AssetStore);
//GUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
if (UnityEngine.Event.current.type == EventType.Repaint)
{
LocalizationEditor.mTestAction = LocalizationEditor.eTest_ActionType.None;
LocalizationEditor.mTestActionArg = null;
LocalizationEditor.mTestActionArg2 = null;
}
}
#endregion
#region References
void OnGUI_References()
{
if (mLocalize.mGUI_ShowReferences = GUITools.DrawHeader ("References", mLocalize.mGUI_ShowReferences))
{
GUITools.BeginContents();
bool canTest = UnityEngine.Event.current.type == EventType.Repaint;
var testAddObj = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Add ? (Object)LocalizationEditor.mTestActionArg : null;
var testReplaceIndx = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Replace ? (int)LocalizationEditor.mTestActionArg : -1;
var testReplaceObj = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Replace ? (Object)LocalizationEditor.mTestActionArg2 : null;
var testDeleteIndx = canTest && LocalizationEditor.mTestAction == LocalizationEditor.eTest_ActionType.Button_Assets_Delete ? (int)LocalizationEditor.mTestActionArg : -1;
bool changed = GUITools.DrawObjectsArray( mProp_TranslatedObjects, false, false, true, testAddObj, testReplaceObj, testReplaceIndx, testDeleteIndx);
if (changed)
{
serializedObject.ApplyModifiedProperties();
foreach (var obj in serializedObject.targetObjects)
(obj as Localize).UpdateAssetDictionary();
}
GUITools.EndContents();
}
}
void RemoveUnusedReferences(Localize cmp)
{
cmp.TranslatedObjects.RemoveAll(x => !IsUsingReference(LocalizationManager.GetTermData(cmp.Term), x) && !IsUsingReference(LocalizationManager.GetTermData(cmp.SecondaryTerm), x));
if (cmp.TranslatedObjects.Count != cmp.mAssetDictionary.Count)
cmp.UpdateAssetDictionary();
}
bool IsUsingReference(TermData termData, Object obj )
{
if (obj == null || termData==null) return false;
string objName = obj.name;
foreach (string translation in termData.Languages)
{
if (translation != null && translation.Contains(objName))
return true;
}
return false;
}
#endregion
#region Terms
int GUI_SelectedTerm;
void OnGUI_Terms()
{
if ((mLocalize.mGUI_ShowTems=GUITools.DrawHeader ("Terms", mLocalize.mGUI_ShowTems)))
{
//--[ tabs: Main and Secondary Terms ]----------------
int oldTab = GUI_SelectedTerm;
if (mLocalize.mLocalizeTarget!=null && mLocalize.mLocalizeTarget.CanUseSecondaryTerm())
{
GUI_SelectedTerm = GUITools.DrawTabs (GUI_SelectedTerm, new[]{"Main", "Secondary"});
}
else
{
GUI_SelectedTerm = 0;
GUITools.DrawTabs (GUI_SelectedTerm, new[]{"Main", ""});
}
GUITools.BeginContents();
TermData termData = null;
if (GUI_SelectedTerm==0) termData = OnGUI_PrimaryTerm( oldTab!=GUI_SelectedTerm );
else termData = OnGUI_SecondaryTerm(oldTab!=GUI_SelectedTerm);
GUITools.EndContents();
//--[ Modifier ]-------------
if (mLocalize.Term != "-" && termData!=null && termData.TermType==eTermType.Text)
{
EditorGUI.BeginChangeCheck();
GUILayout.BeginHorizontal();
GUILayout.Label("Prefix:");
EditorGUILayout.PropertyField(mProp_TermPrefix, GUITools.EmptyContent);
GUILayout.Label("Suffix:");
EditorGUILayout.PropertyField(mProp_TermSuffix, GUITools.EmptyContent);
GUILayout.EndHorizontal();
if (EditorGUI.EndChangeCheck())
{
EditorApplication.delayCall += () =>
{
if (targets != null)
{
foreach (var t in targets)
if (t as Localize != null)
(t as Localize).OnLocalize(true);
}
};
}
EditorGUI.BeginChangeCheck();
int val = EditorGUILayout.Popup("Modifier", GUI_SelectedTerm == 0 ? (int)mLocalize.PrimaryTermModifier : (int)mLocalize.SecondaryTermModifier, Enum.GetNames(typeof(Localize.TermModification)));
if (EditorGUI.EndChangeCheck())
{
serializedObject.FindProperty(GUI_SelectedTerm == 0 ? "PrimaryTermModifier" : "SecondaryTermModifier").enumValueIndex = val;
GUI.changed = false;
}
}
OnGUI_Options();
//--[ OnAwake vs OnEnable ]-------------
//GUILayout.BeginHorizontal();
//mProp_LocalizeOnAwake.boolValue = GUILayout.Toggle(mProp_LocalizeOnAwake.boolValue, new GUIContent(" Pre-Localize on Awake", "Localizing on Awake could result in a lag when the level is loaded but faster later when objects are enabled. If false, it will Localize OnEnable, so will yield faster level load but could have a lag when screens are enabled"));
//GUILayout.FlexibleSpace();
//if (mLocalize.HasCallback())
//{
// GUI.enabled = false;
// GUILayout.Toggle(true, new GUIContent(" Force Localize", "Enable this when the translations have parameters (e.g. Thew winner is {[WINNER}]) to prevent any optimization that could prevent updating the translation when the object is enabled"));
// GUI.enabled = true;
//}
//else
//{
// mProp_AlwaysForceLocalize.boolValue = GUILayout.Toggle(mProp_AlwaysForceLocalize.boolValue, new GUIContent(" Force Localize", "Enable this when the translations have parameters (e.g. Thew winner is {[WINNER}]) to prevent any optimization that could prevent updating the translation when the object is enabled"));
//}
//GUILayout.EndHorizontal();
//--[ Right To Left ]-------------
if (!mLocalize.IgnoreRTL && mLocalize.Term!="-" && termData != null && termData.TermType == eTermType.Text)
{
GUILayout.BeginVertical("Box");
//GUILayout.BeginHorizontal();
// mProp_IgnoreRTL.boolValue = GUILayout.Toggle(mProp_IgnoreRTL.boolValue, new GUIContent(" Ignore Right To Left", "Arabic and other RTL languages require processing them so they render correctly, this toogle allows ignoring that processing (in case you are doing it manually during a callback)"));
// GUILayout.FlexibleSpace();
// mProp_SeparateWords.boolValue = GUILayout.Toggle(mProp_SeparateWords.boolValue, new GUIContent(" Separate Words", " Some languages (e.g. Chinese, Japanese and Thai) don't add spaces to their words (all characters are placed toguether), enabling this checkbox, will add spaces to all characters to allow wrapping long texts into multiple lines."));
//GUILayout.EndHorizontal();
{
mProp_MaxCharactersInRTL.intValue = EditorGUILayout.IntField( new GUIContent("Max line length", "If the language is Right To Left, long lines will be split at this length and the RTL fix will be applied to each line, this should be set to the maximum number of characters that fit in this text width. 0 disables the per line fix"), mProp_MaxCharactersInRTL.intValue );
GUILayout.BeginHorizontal();
mProp_CorrectAlignmentForRTL.boolValue = GUILayout.Toggle(mProp_CorrectAlignmentForRTL.boolValue, new GUIContent(" Adjust Alignment", "Right-align when Right-To-Left Language, and Left-Align otherwise") );
GUILayout.FlexibleSpace();
mProp_IgnoreNumbersInRTL.boolValue = GUILayout.Toggle(mProp_IgnoreNumbersInRTL.boolValue, new GUIContent(" Ignore Numbers", "Preserve numbers as latin characters instead of converting them"));
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
////GUILayout.EndHorizontal();
}
}
void OnGUI_Options()
{
int mask = 0;
if (mProp_LocalizeOnAwake.boolValue) mask |= 1 << 0;
if (mProp_AlwaysForceLocalize.boolValue) mask |= 1 << 1;
if (mProp_AllowParameters.boolValue) mask |= 1 << 2;
if (mProp_AllowLocalizedParameters.boolValue) mask |= 1 << 3;
if (mProp_SeparateWords.boolValue) mask |= 1 << 4;
if (mProp_IgnoreRTL.boolValue) mask |= 1 << 5;
EditorGUI.BeginChangeCheck();
mask = EditorGUILayout.MaskField(new GUIContent("Options"), mask, new []{
"Localize On Awake",
"Force Localize",
"Allow Parameters",
"Allow Localized Parameters",
"Separate Words",
"Ignore RTL"
});
if (EditorGUI.EndChangeCheck())
{
mProp_LocalizeOnAwake.boolValue = (mask & (1 << 0))> 0;
mProp_AlwaysForceLocalize.boolValue = (mask & (1 << 1))> 0;
mProp_AllowParameters.boolValue = (mask & (1 << 2))> 0;
mProp_AllowLocalizedParameters.boolValue = (mask & (1 << 3))> 0;
mProp_SeparateWords.boolValue = (mask & (1 << 4))> 0;
mProp_IgnoreRTL.boolValue = (mask & (1 << 5))> 0;
}
}
TermData OnGUI_PrimaryTerm( bool OnOpen )
{
string Key = mLocalize.mTerm;
if (string.IsNullOrEmpty(Key))
{
string SecondaryTerm;
mLocalize.GetFinalTerms( out Key, out SecondaryTerm );
}
if (OnOpen) mNewKeyName = Key;
if ( OnGUI_SelectKey( ref Key, string.IsNullOrEmpty(mLocalize.mTerm)))
mProp_mTerm.stringValue = Key;
return LocalizationEditor.OnGUI_Keys_Languages( Key, mLocalize );
}
TermData OnGUI_SecondaryTerm( bool OnOpen )
{
string Key = mLocalize.mTermSecondary;
if (string.IsNullOrEmpty(Key))
{
string ss;
mLocalize.GetFinalTerms( out ss, out Key );
}
if (OnOpen) mNewKeyName = Key;
if ( OnGUI_SelectKey( ref Key, string.IsNullOrEmpty(mLocalize.mTermSecondary)))
mProp_mTermSecondary.stringValue = Key;
return LocalizationEditor.OnGUI_Keys_Languages( Key, mLocalize, false );
}
bool OnGUI_SelectKey( ref string Term, bool Inherited ) // Inherited==true means that the mTerm is empty and we are using the Label.text instead
{
GUILayout.Space (5);
GUILayout.BeginHorizontal();
GUI.changed = false;
mAllowEditKeyName = GUILayout.Toggle(mAllowEditKeyName, "Term:", EditorStyles.foldout, GUILayout.ExpandWidth(false));
if (GUI.changed && mAllowEditKeyName) {
mNewKeyName = Term;
mTermsArray = null;
}
bool bChanged = false;
if (mTermsArray==null || Term!="-" && Array.IndexOf(mTermsArray, Term)<0)
UpdateTermsList(Term);
if (Inherited)
GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
int Index = Term=="-" || Term=="" ? mTermsArray.Length-1 : Array.IndexOf( mTermsArray, Term );
GUI.changed = false;
int newIndex = EditorGUILayout.Popup( Index, mTermsArray);
GUI.contentColor = Color.white;
if (/*newIndex != Index && newIndex>=0*/GUI.changed)
{
GUI.changed = false;
if (mLocalize.Source != null && newIndex == mTermsArray.Length - 4) //< show terms from all sources >
{
mLocalize.Source = null;
mTermsArray = null;
}
else
if (newIndex == mTermsArray.Length - 2) //<inferred from text>
mNewKeyName = Term = string.Empty;
else
if (newIndex == mTermsArray.Length - 1) //<none>
mNewKeyName = Term = "-";
else
mNewKeyName = Term = mTermsArray[newIndex];
if (GUI_SelectedTerm==0)
mLocalize.SetTerm (mNewKeyName);
else
mLocalize.SetTerm (null, mNewKeyName);
mAllowEditKeyName = false;
bChanged = true;
}
LanguageSourceData source = LocalizationManager.GetSourceContaining(Term);
TermData termData = source.GetTermData(Term);
if (termData!=null)
{
if (Inherited)
bChanged = true; // if the term its inferred and a matching term its found, then use that
eTermType NewType = (eTermType)EditorGUILayout.EnumPopup(termData.TermType, GUILayout.Width(90));
if (termData.TermType != NewType)
termData.TermType = NewType;
}
GUILayout.EndHorizontal();
if (mAllowEditKeyName)
{
GUILayout.BeginHorizontal(GUILayout.Height (1));
GUILayout.BeginHorizontal(EditorStyles.toolbar);
if(mNewKeyName==null) mNewKeyName = string.Empty;
GUI.changed = false;
mNewKeyName = EditorGUILayout.TextField(mNewKeyName, new GUIStyle(GUITools.Style_ToolbarSearchTextField), GUILayout.ExpandWidth(true));
if (GUI.changed)
{
mTermsArray = null; // regenerate this array to apply filtering
GUI.changed = false;
}
if (GUILayout.Button (string.Empty, string.IsNullOrEmpty(mNewKeyName) ? GUITools.Style_ToolbarSearchCancelButtonEmpty : GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth(false)))
{
mTermsArray = null; // regenerate this array to apply filtering
mNewKeyName = string.Empty;
}
GUILayout.EndHorizontal();
string ValidatedName = mNewKeyName;
LanguageSourceData.ValidateFullTerm( ref ValidatedName );
bool CanUseNewName = source.GetTermData(ValidatedName)==null;
GUI.enabled = !string.IsNullOrEmpty(mNewKeyName) && CanUseNewName;
if (GUILayout.Button ("Create", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
mNewKeyName = ValidatedName;
mTermsArray=null; // this recreates that terms array
LanguageSourceData Source = null;
#if UNITY_EDITOR
if (mLocalize.Source!=null)
Source = mLocalize.Source.SourceData;
#endif
if (Source==null)
Source = LocalizationManager.Sources[0];
Term = mNewKeyName;
var data = Source.AddTerm( mNewKeyName, eTermType.Text, false );
if (data.Languages.Length > 0)
data.Languages[0] = mLocalize.GetMainTargetsText();
Source.Editor_SetDirty();
AssetDatabase.SaveAssets();
mAllowEditKeyName = false;
bChanged = true;
GUIUtility.keyboardControl = 0;
}
GUI.enabled = termData!=null && !string.IsNullOrEmpty(mNewKeyName) && CanUseNewName;
if (GUILayout.Button (new GUIContent("Rename","Renames the term in the source and updates every object using it in the current scene"), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
mNewKeyName = ValidatedName;
Term = mNewKeyName;
mTermsArray=null; // this recreates that terms array
mAllowEditKeyName = false;
bChanged = true;
LocalizationEditor.TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
LocalizationEditor.TermReplacements[ termData.Term ] = mNewKeyName;
termData.Term = mNewKeyName;
source.UpdateDictionary(true);
LocalizationEditor.ReplaceTermsInCurrentScene();
GUIUtility.keyboardControl = 0;
EditorApplication.update += LocalizationEditor.DoParseTermsInCurrentScene;
}
GUI.enabled = true;
GUILayout.EndHorizontal();
bChanged |= OnGUI_SelectKey_PreviewTerms ( ref Term);
}
GUILayout.Space (5);
return bChanged;
}
void UpdateTermsList( string currentTerm )
{
List<string> Terms = mLocalize.Source==null ? LocalizationManager.GetTermsList() : mLocalize.Source.SourceData.GetTermsList();
// If there is a filter, remove all terms not matching that filter
if (mAllowEditKeyName && !string.IsNullOrEmpty(mNewKeyName))
{
string Filter = mNewKeyName.ToUpper();
for (int i=Terms.Count-1; i>=0; --i)
if (!Terms[i].ToUpper().Contains(Filter) && Terms[i]!=currentTerm)
Terms.RemoveAt(i);
}
if (!string.IsNullOrEmpty(currentTerm) && currentTerm!="-" && !Terms.Contains(currentTerm))
Terms.Add (currentTerm);
Terms.Sort(StringComparer.OrdinalIgnoreCase);
Terms.Add("");
if (mLocalize.Source != null)
{
Terms.Add("< Show Terms from all sources >");
Terms.Add("");
}
Terms.Add("<inferred from text>");
Terms.Add("<none>");
mTermsArray = Terms.ToArray();
}
bool OnGUI_SelectKey_PreviewTerms ( ref string Term)
{
if (mTermsArray==null)
UpdateTermsList(Term);
int nTerms = mTermsArray.Length;
if (nTerms<=0)
return false;
if (nTerms==1 && mTermsArray[0]==Term)
return false;
bool bChanged = false;
GUI.backgroundColor = Color.gray;
GUILayout.BeginVertical (GUIStyle_OldTextArea);
for (int i = 0, imax = Mathf.Min (nTerms, 3); i < imax; ++i)
{
ParsedTerm parsedTerm;
int nUses = -1;
if (LocalizationEditor.mParsedTerms.TryGetValue (mTermsArray [i], out parsedTerm))
nUses = parsedTerm.Usage;
string FoundText = mTermsArray [i];
if (nUses > 0)
FoundText = string.Concat ("(", nUses, ") ", FoundText);
if (GUILayout.Button (FoundText, EditorStyles.miniLabel, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 70)))
{
if (mTermsArray[i] == "<inferred from text>")
mNewKeyName = Term = string.Empty;
else
if (mTermsArray[i] == "<none>")
mNewKeyName = Term = "-";
else
if (mTermsArray[i] != "< Show Terms from all sources >")
mNewKeyName = Term = mTermsArray[i];
//mNewKeyName = Term = (mTermsArray [i]=="<inferred from text>" ? string.Empty : mTermsArray [i]);
GUIUtility.keyboardControl = 0;
mAllowEditKeyName = false;
bChanged = true;
}
}
if (nTerms > 3)
GUILayout.Label ("...");
GUILayout.EndVertical ();
GUI.backgroundColor = Color.white;
return bChanged;
}
#endregion
#region Target
void OnGUI_Target()
{
List<string> TargetTypes = new List<string>();
int CurrentTarget = -1;
mLocalize.FindTarget();
foreach (var desc in LocalizationManager.mLocalizeTargets)
{
if (desc.CanLocalize(mLocalize))
{
TargetTypes.Add(desc.Name);
if (mLocalize.mLocalizeTarget!=null && desc.GetTargetType() == mLocalize.mLocalizeTarget.GetType())
CurrentTarget = TargetTypes.Count - 1;
}
}
if (CurrentTarget==-1)
{
CurrentTarget = TargetTypes.Count;
TargetTypes.Add("None");
}
GUILayout.BeginHorizontal();
GUILayout.Label ("Target:", GUILayout.Width (60));
EditorGUI.BeginChangeCheck();
int index = EditorGUILayout.Popup(CurrentTarget, TargetTypes.ToArray());
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
foreach (var obj in serializedObject.targetObjects)
{
var cmp = obj as Localize;
if (cmp == null)
continue;
if (cmp.mLocalizeTarget != null)
DestroyImmediate(cmp.mLocalizeTarget);
cmp.mLocalizeTarget = null;
foreach (var desc in LocalizationManager.mLocalizeTargets)
{
if (desc.Name == TargetTypes[index])
{
cmp.mLocalizeTarget = desc.CreateTarget(cmp);
cmp.mLocalizeTargetName = desc.GetTargetType().ToString();
break;
}
}
}
serializedObject.Update();
}
GUILayout.EndHorizontal();
}
#endregion
#region Source
void OnGUI_Source()
{
GUILayout.BeginHorizontal();
ILanguageSource currentSource = mLocalize.Source;
if (currentSource==null)
{
LanguageSourceData source = LocalizationManager.GetSourceContaining(mLocalize.Term);
currentSource = source==null ? null : source.owner;
}
if (GUILayout.Button("Open Source", EditorStyles.toolbarButton, GUILayout.Width (100)))
{
Selection.activeObject = currentSource as Object;
string sTerm, sSecondary;
mLocalize.GetFinalTerms( out sTerm, out sSecondary );
if (GUI_SelectedTerm==1) sTerm = sSecondary;
LocalizationEditor.mKeyToExplore = sTerm;
}
GUILayout.Space (2);
GUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUI.BeginChangeCheck ();
if (mLocalize.Source == null)
{
GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
}
Object obj = EditorGUILayout.ObjectField(currentSource as Object, typeof(Object), true);
GUI.contentColor = Color.white;
if (EditorGUI.EndChangeCheck())
{
ILanguageSource NewSource = obj as ILanguageSource;
if (NewSource == null && obj as GameObject != null)
{
NewSource = (obj as GameObject).GetComponent<LanguageSource>();
}
mLocalize.Source = NewSource;
string sTerm, sSecondary;
mLocalize.GetFinalTerms(out sTerm, out sSecondary);
if (GUI_SelectedTerm == 1) sTerm = sSecondary;
UpdateTermsList(sTerm);
}
if (GUILayout.Button(new GUIContent("Detect", "Finds the LanguageSource containing the selected term, the term list will now only show terms inside that source."), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
string sTerm, sSecondary;
mLocalize.GetFinalTerms(out sTerm, out sSecondary);
if (GUI_SelectedTerm == 1) sTerm = sSecondary;
var data = LocalizationManager.GetSourceContaining(sTerm, false);
mLocalize.Source = data==null ? null : data.owner;
mTermsArray = null;
}
GUILayout.EndHorizontal();
GUILayout.EndHorizontal();
}
#endregion
#region Event CallBack
//public void DrawEventCallBack( EventCallback CallBack, Localize loc )
//{
//if (CallBack==null)
// return;
//GUI.changed = false;
//GUILayout.BeginHorizontal();
//GUILayout.Label("Target:", GUILayout.ExpandWidth(false));
//CallBack.Target = EditorGUILayout.ObjectField( CallBack.Target, typeof(MonoBehaviour), true) as MonoBehaviour;
//GUILayout.EndHorizontal();
//if (CallBack.Target!=null)
//{
// GameObject GO = CallBack.Target.gameObject;
// List<MethodInfo> Infos = new List<MethodInfo>();
// var targets = GO.GetComponents(typeof(MonoBehaviour));
// foreach (var behavior in targets)
// Infos.AddRange( behavior.GetType().GetMethods() );
// List<string> Methods = new List<string>();
// for (int i = 0, imax=Infos.Count; i<imax; ++i)
// {
// MethodInfo mi = Infos[i];
// if (IsValidMethod(mi))
// Methods.Add (mi.Name);
// }
// int Index = Methods.IndexOf(CallBack.MethodName);
// int NewIndex = EditorGUILayout.Popup(Index, Methods.ToArray(), GUILayout.ExpandWidth(true));
// if (NewIndex!=Index)
// CallBack.MethodName = Methods[ NewIndex ];
//}
//if (GUI.changed)
//{
// GUI.changed = false;
// EditorUtility.SetDirty(loc);
// //UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty() EditorApplication.MakeSceneDirty();
//}
//}
static bool IsValidMethod( MethodInfo mi )
{
if (mi.DeclaringType == typeof(MonoBehaviour) || mi.ReturnType != typeof(void))
return false;
ParameterInfo[] Params = mi.GetParameters ();
if (Params.Length == 0) return true;
if (Params.Length > 1) return false;
if (Params [0].ParameterType.IsSubclassOf (typeof(Object))) return true;
if (Params [0].ParameterType == typeof(Object)) return true;
return false;
}
#endregion
#region Styles
public static GUIStyle GUIStyle_Header {
get{
if (mGUIStyle_Header==null)
{
mGUIStyle_Header = new GUIStyle("HeaderLabel");
mGUIStyle_Header.fontSize = 25;
mGUIStyle_Header.normal.textColor = Color.Lerp(Color.white, Color.gray, 0.5f);
mGUIStyle_Header.fontStyle = FontStyle.BoldAndItalic;
mGUIStyle_Header.alignment = TextAnchor.UpperCenter;
}
return mGUIStyle_Header;
}
}
static GUIStyle mGUIStyle_Header;
public static GUIStyle GUIStyle_SubHeader {
get{
if (mGUIStyle_SubHeader==null)
{
mGUIStyle_SubHeader = new GUIStyle("HeaderLabel");
mGUIStyle_SubHeader.fontSize = 13;
mGUIStyle_SubHeader.fontStyle = FontStyle.Normal;
mGUIStyle_SubHeader.margin.top = -50;
mGUIStyle_SubHeader.alignment = TextAnchor.UpperCenter;
}
return mGUIStyle_SubHeader;
}
}
static GUIStyle mGUIStyle_SubHeader;
public static GUIStyle GUIStyle_Background {
get{
if (mGUIStyle_Background==null)
{
mGUIStyle_Background = new GUIStyle(EditorStyles.textArea);
mGUIStyle_Background.fixedHeight = 0;
mGUIStyle_Background.overflow.left = 50;
mGUIStyle_Background.overflow.right = 50;
mGUIStyle_Background.overflow.top = -5;
mGUIStyle_Background.overflow.bottom = 0;
}
return mGUIStyle_Background;
}
}
static GUIStyle mGUIStyle_Background;
public static GUIStyle GUIStyle_OldTextArea
{
get
{
if (mGUIStyle_OldTextArea == null)
{
mGUIStyle_OldTextArea = new GUIStyle(EditorStyles.textArea);
mGUIStyle_OldTextArea.fixedHeight = 0;
}
return mGUIStyle_OldTextArea;
}
}
static GUIStyle mGUIStyle_OldTextArea;
#endregion
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 675119279b2a30245801272112cfbe38
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
[CustomEditor(typeof(ResourceManager))]
public class ResourceManagerInspector : UnityEditor.Editor
{
SerializedProperty mAssets;
void OnEnable()
{
UpgradeManager.EnablePlugins();
mAssets = serializedObject.FindProperty("Assets");
}
public override void OnInspectorGUI()
{
GUILayout.Space(5);
GUITools.DrawHeader("Assets:", true);
GUITools.BeginContents();
///GUILayout.Label ("Assets:");
GUITools.DrawObjectsArray( mAssets );
GUITools.EndContents();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ba2fdf8face79dd4f9e1ed80448db843
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using System;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
[CustomEditor(typeof(SetLanguage))]
public class SetLanguageInspector : UnityEditor.Editor
{
public SetLanguage setLan;
public SerializedProperty mProp_Language;
public void OnEnable()
{
setLan = (SetLanguage)target;
mProp_Language = serializedObject.FindProperty("_Language");
}
public override void OnInspectorGUI()
{
string[] Languages;
LanguageSource sourceObj = setLan.mSource;
if (sourceObj == null)
{
LocalizationManager.UpdateSources();
Languages = LocalizationManager.GetAllLanguages().ToArray();
Array.Sort(Languages);
}
else
{
Languages = sourceObj.mSource.GetLanguages().ToArray();
Array.Sort(Languages);
}
int index = Array.IndexOf(Languages, mProp_Language.stringValue);
GUI.changed = false;
index = EditorGUILayout.Popup("Language", index, Languages);
if (GUI.changed)
{
if (index<0 || index>=Languages.Length)
mProp_Language.stringValue = string.Empty;
else
mProp_Language.stringValue = Languages[index];
GUI.changed = false;
serializedObject.ApplyModifiedProperties();
}
GUILayout.Space(5);
if (setLan.mSource==null) GUI.contentColor = Color.Lerp (Color.gray, Color.yellow, 0.1f);
sourceObj = EditorGUILayout.ObjectField("Language Source:", sourceObj, typeof(LanguageSource), true) as LanguageSource;
GUI.contentColor = Color.white;
if (GUI.changed)
setLan.mSource = sourceObj;
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7af58b4da44670e47a509c59754e8c2b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
[CustomPropertyDrawer (typeof (TermsPopup))]
public class TermsPopup_Drawer : PropertyDrawer
{
GUIContent[] mTerms_Context;
int nFramesLeftBeforeUpdate;
string mPrevFilter;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var filter = ((TermsPopup)attribute).Filter;
ShowGUICached(position, property, label, null, filter, ref mTerms_Context, ref nFramesLeftBeforeUpdate, ref mPrevFilter);
}
public static bool ShowGUI(Rect position, SerializedProperty property, GUIContent label, LanguageSourceData source, string filter = "")
{
GUIContent[] terms=null;
int framesLeftBeforeUpdate=0;
string prevFilter = null;
return ShowGUICached(position, property, label, source, filter, ref terms, ref framesLeftBeforeUpdate, ref prevFilter);
}
public static bool ShowGUICached(Rect position, SerializedProperty property, GUIContent label, LanguageSourceData source, string filter, ref GUIContent[] terms_Contexts, ref int framesBeforeUpdating, ref string prevFilter)
{
UpdateTermsCache(source, filter, ref terms_Contexts, ref framesBeforeUpdating, ref prevFilter);
label = EditorGUI.BeginProperty(position, label, property);
EditorGUI.BeginChangeCheck ();
var index = property.stringValue == "-" || property.stringValue == "" ? terms_Contexts.Length - 1 :
property.stringValue == " " ? terms_Contexts.Length - 2 :
GetTermIndex(terms_Contexts, property.stringValue);
var newIndex = EditorGUI.Popup(position, label, index, terms_Contexts);
if (EditorGUI.EndChangeCheck())
{
property.stringValue = newIndex < 0 || newIndex == terms_Contexts.Length - 1 ? string.Empty : terms_Contexts[newIndex].text;
if (newIndex == terms_Contexts.Length - 1)
property.stringValue = "-";
else
if (newIndex < 0 || newIndex == terms_Contexts.Length - 2)
property.stringValue = string.Empty;
else
property.stringValue = terms_Contexts[newIndex].text;
EditorGUI.EndProperty();
return true;
}
EditorGUI.EndProperty();
return false;
}
static int GetTermIndex(GUIContent[] terms_Contexts, string term )
{
for (int i = 0; i < terms_Contexts.Length; ++i)
if (terms_Contexts[i].text == term)
return i;
return -1;
}
static void UpdateTermsCache(LanguageSourceData source, string filter, ref GUIContent[] terms_Contexts, ref int framesBeforeUpdating, ref string prevFilter)
{
framesBeforeUpdating--;
if (terms_Contexts!=null && framesBeforeUpdating>0 && filter==prevFilter)
{
return;
}
framesBeforeUpdating = 60;
prevFilter = filter;
var Terms = source == null ? LocalizationManager.GetTermsList() : source.GetTermsList();
if (string.IsNullOrEmpty(filter) == false)
{
Terms = Filter(Terms, filter);
}
Terms.Sort(StringComparer.OrdinalIgnoreCase);
Terms.Add("");
Terms.Add("<inferred from text>");
Terms.Add("<none>");
terms_Contexts = DisplayOptions(Terms);
}
private static List<string> Filter(List<string> terms, string filter)
{
var filtered = new List<string>();
for (var i = 0; i < terms.Count; i++)
{
var term = terms[i];
if (term.Contains(filter))
{
filtered.Add(term);
}
}
return filtered;
}
private static GUIContent[] DisplayOptions(IList<string> terms)
{
var options = new GUIContent[terms.Count];
for (var i = 0; i < terms.Count; i++)
{
options[i] = new GUIContent(terms[i]);
}
return options;
}
}
[CustomPropertyDrawer(typeof(LocalizedString))]
public class LocalizedStringDrawer : PropertyDrawer
{
GUIContent[] mTerms_Context;
int nFramesLeftBeforeUpdate;
string mPrevFilter;
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
var termRect = rect; termRect.xMax -= 50;
var termProp = property.FindPropertyRelative("mTerm");
TermsPopup_Drawer.ShowGUICached(termRect, termProp, label, null, "", ref mTerms_Context, ref nFramesLeftBeforeUpdate, ref mPrevFilter);
var maskRect = rect; maskRect.xMin = maskRect.xMax - 30;
var termIgnoreRTL = property.FindPropertyRelative("mRTL_IgnoreArabicFix");
var termConvertNumbers = property.FindPropertyRelative("mRTL_ConvertNumbers");
var termDontLocalizeParams = property.FindPropertyRelative("m_DontLocalizeParameters");
int mask = (termIgnoreRTL.boolValue ? 0 : 1) +
(termConvertNumbers.boolValue ? 0 : 2) +
(termDontLocalizeParams.boolValue ? 0 : 4);
int newMask = EditorGUI.MaskField(maskRect, mask, new[] { "Arabic Fix", "Ignore Numbers in RTL", "Localize Parameters" });
if (newMask != mask)
{
termIgnoreRTL.boolValue = (newMask & 1) == 0;
termConvertNumbers.boolValue = (newMask & 2) == 0;
termDontLocalizeParams.boolValue = (newMask & 4) == 0;
}
var showRect = rect; showRect.xMin = termRect.xMax; showRect.xMax=maskRect.xMin;
bool enabled = GUI.enabled;
GUI.enabled = enabled & (!string.IsNullOrEmpty (termProp.stringValue) && termProp.stringValue!="-");
if (GUI.Button (showRect, "?"))
{
var source = LocalizationManager.GetSourceContaining(termProp.stringValue);
LocalizationEditor.mKeyToExplore = termProp.stringValue;
Selection.activeObject = source.ownerObject;
}
GUI.enabled = enabled;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 51c22a426b92fa84cb6ca7b75176da8a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8ad136296e8e6e14eaa2726ac1992b6c
folderAsset: yes
timeCreated: 1461137613
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,308 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
public enum eViewMode { ImportExport, Keys, Languages, Tools, References }
public static eViewMode mCurrentViewMode = eViewMode.Keys;
public enum eSpreadsheetMode { Local, Google }
public eSpreadsheetMode mSpreadsheetMode = eSpreadsheetMode.Google;
public static string mLocalizationMsg = "";
public static MessageType mLocalizationMessageType = MessageType.None;
// These variables are for executing action from Unity Tests
public enum eTest_ActionType { None, Button_AddLanguageFromPopup, Button_AddLanguageManual,
Button_AddTerm_InTermsList, Button_AddSelectedTerms,
Button_RemoveSelectedTerms, Button_DeleteTerm,
Button_SelectTerms_All, Button_SelectTerms_None, Button_SelectTerms_Used, Button_SelectTerms_Missing,
Button_Term_Translate, Button_Term_TranslateAll, Button_Languages_TranslateAll,
Button_Assets_Add, Button_Assets_Replace, Button_Assets_Delete,
Button_GoogleSpreadsheet_RefreshList, Button_GoogleSpreadsheet_Export, Button_GoogleSpreadsheet_Import
}
public static eTest_ActionType mTestAction = eTest_ActionType.None;
public static object mTestActionArg, mTestActionArg2;
#endregion
#region Editor
/*[MenuItem("Window/Localization", false)]
public static void OpenLocalizationEditor()
{
EditorWindow.GetWindow<LocalizationEditor>(false, "Localization", true);
}*/
#endregion
#region GUI
void InitializeStyles()
{
Style_ToolBar_Big = new GUIStyle(EditorStyles.toolbar);
Style_ToolBar_Big.fixedHeight = Style_ToolBar_Big.fixedHeight*1.5f;
Style_ToolBarButton_Big = new GUIStyle(EditorStyles.toolbarButton);
Style_ToolBarButton_Big.fixedHeight = Style_ToolBarButton_Big.fixedHeight*1.5f;
}
void OnGUI_Main()
{
OnGUI_Warning_SourceInScene();
OnGUI_Warning_SourceInsidePluginsFolder();
OnGUI_Warning_SourceNotUpToDate();
var prevViewMode = mCurrentViewMode;
GUILayout.BeginHorizontal();
//OnGUI_ToggleEnumBig( "Spreadsheets", ref mCurrentViewMode, eViewMode.ImportExport, GUI.skin.GetStyle("CN EntryWarn").normal.background, "External Spreadsheet File or Service" );
OnGUI_ToggleEnumBig( "Spreadsheets", ref mCurrentViewMode, eViewMode.ImportExport, null, "External Spreadsheet File or Service" );
OnGUI_ToggleEnumBig( "Terms", ref mCurrentViewMode, eViewMode.Keys, null, null );
OnGUI_ToggleEnumBig( "Languages", ref mCurrentViewMode, eViewMode.Languages, null, null );
OnGUI_ToggleEnumBig( "Tools", ref mCurrentViewMode, eViewMode.Tools, null, null );
OnGUI_ToggleEnumBig( "Assets", ref mCurrentViewMode, eViewMode.References, null, null );
GUILayout.EndHorizontal();
//GUILayout.Space(10);
switch (mCurrentViewMode)
{
case eViewMode.ImportExport : OnGUI_ImportExport(); break;
case eViewMode.Keys : OnGUI_KeysList(); break;
case eViewMode.Languages : OnGUI_Languages(); break;
case eViewMode.Tools : OnGUI_Tools(prevViewMode != mCurrentViewMode); break;
case eViewMode.References : OnGUI_References(); break;
}
}
void OnGUI_ImportExport()
{
eSpreadsheetMode OldMode = mSpreadsheetMode;
mSpreadsheetMode = (eSpreadsheetMode)GUITools.DrawShadowedTabs ((int)mSpreadsheetMode, new[]{"Local", "Google"});
if (mSpreadsheetMode != OldMode)
ClearErrors();
GUITools.BeginContents();
switch (mSpreadsheetMode)
{
case eSpreadsheetMode.Local : OnGUI_Spreadsheet_Local(); break;
case eSpreadsheetMode.Google : OnGUI_Spreadsheet_Google(); break;
}
GUITools.EndContents(false);
}
void OnGUI_References()
{
EditorGUILayout.HelpBox("These are the assets that are referenced by the Terms and not in the Resources folder", MessageType.Info);
bool canTest = UnityEngine.Event.current.type == EventType.Repaint;
var testAddObj = canTest && mTestAction == eTest_ActionType.Button_Assets_Add ? (Object)mTestActionArg : null;
var testReplaceIndx = canTest && mTestAction == eTest_ActionType.Button_Assets_Replace ? (int)mTestActionArg : -1;
var testReplaceObj = canTest && mTestAction == eTest_ActionType.Button_Assets_Replace ? (Object)mTestActionArg2 : null;
var testDeleteIndx = canTest && mTestAction == eTest_ActionType.Button_Assets_Delete ? (int)mTestActionArg : -1;
bool changed = GUITools.DrawObjectsArray( mProp_Assets, false, false, false, testAddObj, testReplaceObj, testReplaceIndx, testDeleteIndx);
if (changed)
{
serializedObject.ApplyModifiedProperties();
foreach (var obj in serializedObject.targetObjects)
(obj as LanguageSource).mSource.UpdateAssetDictionary();
}
}
#endregion
#region Misc
void OnGUI_ToggleEnumBig<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip) { OnGUI_ToggleEnum( text, ref currentMode, newMode, texture, tooltip, Style_ToolBarButton_Big); }
void OnGUI_ToggleEnumSmall<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip) { OnGUI_ToggleEnum( text, ref currentMode, newMode, texture, tooltip, EditorStyles.toolbarButton); }
void OnGUI_ToggleEnum<Enum>( string text, ref Enum currentMode, Enum newMode, Texture texture, string tooltip, GUIStyle style)
{
GUI.changed = false;
if (GUILayout.Toggle( currentMode.Equals(newMode), new GUIContent(text, texture, tooltip), style, GUILayout.ExpandWidth(true)))
{
currentMode = newMode;
if (GUI.changed)
ClearErrors();
}
}
int OnGUI_FlagToogle( string Text, string tooltip, int flags, int bit )
{
bool State = (flags & bit)>0;
bool NewState = GUILayout.Toggle(State, new GUIContent(Text, tooltip), "toolbarbutton");
if (State!=NewState)
{
if (!NewState && flags==bit)
return flags;
flags = NewState ? flags | bit : flags & ~bit;
}
return flags;
}
void OnGUI_SelectableToogleListItem( string Element, ref List<string> Selections, string Style )
{
bool WasEnabled = Selections.Contains(Element);
bool IsEnabled = GUILayout.Toggle( WasEnabled, "", Style, GUILayout.ExpandWidth(false) );
if (IsEnabled && !WasEnabled)
Selections.Add(Element);
else
if (!IsEnabled && WasEnabled)
Selections.Remove(Element);
}
void OnGUI_SelectableToogleListItem( Rect rect, string Element, ref List<string> Selections, string Style )
{
bool WasEnabled = Selections.Contains(Element);
bool IsEnabled = GUI.Toggle( rect, WasEnabled, "", Style );
if (IsEnabled && !WasEnabled)
Selections.Add(Element);
else
if (!IsEnabled && WasEnabled)
Selections.Remove(Element);
}
static bool InTestAction( eTest_ActionType testType )
{
return mTestAction == testType && UnityEngine.Event.current.type == EventType.Repaint;
}
static bool TestButton(eTest_ActionType action, string text, GUIStyle style, params GUILayoutOption[] options)
{
return GUILayout.Button(text, style, options) || mTestAction == action && UnityEngine.Event.current.type == EventType.Repaint;
}
static bool TestButtonArg(eTest_ActionType action, object arg, string text, GUIStyle style, params GUILayoutOption[] options)
{
return GUILayout.Button(text, style, options) || mTestAction == action && (mTestActionArg==null || mTestActionArg.Equals(arg)) && UnityEngine.Event.current.type == EventType.Repaint;
}
static bool TestButton(eTest_ActionType action, GUIContent text, GUIStyle style, params GUILayoutOption[] options)
{
return GUILayout.Button(text, style, options) || mTestAction == action && UnityEngine.Event.current.type == EventType.Repaint;
}
static bool TestButtonArg(eTest_ActionType action, object arg, GUIContent text, GUIStyle style, params GUILayoutOption[] options)
{
return GUILayout.Button(text, style, options) || mTestAction == action && (mTestActionArg == null || mTestActionArg.Equals(arg)) && UnityEngine.Event.current.type == EventType.Repaint;
}
#endregion
#region Error Management
static void OnGUI_ShowMsg()
{
if (!string.IsNullOrEmpty(mLocalizationMsg))
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox(mLocalizationMsg, mLocalizationMessageType);
GUILayout.Space(-5);
GUILayout.BeginVertical(GUILayout.Width(15), GUILayout.ExpandHeight(false));
GUILayout.Space(15);
if (GUILayout.Button("X", GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth(false)))
ClearErrors();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.Space(8);
}
}
static void ShowError ( string Error, bool ShowInConsole = true ) { ShowMessage ( Error, MessageType.Error, ShowInConsole ); }
static void ShowInfo ( string Msg, bool ShowInConsole = false ) { ShowMessage ( Msg, MessageType.Info, ShowInConsole ); }
static void ShowWarning( string Msg, bool ShowInConsole = true) { ShowMessage ( Msg, MessageType.Warning, ShowInConsole ); }
static void ShowMessage( string Msg, MessageType msgType, bool ShowInConsole )
{
if (string.IsNullOrEmpty(Msg))
Msg = string.Empty;
mLocalizationMsg = Msg;
mLocalizationMessageType = msgType;
if (ShowInConsole)
{
switch (msgType)
{
case MessageType.Error : Debug.LogError(Msg); break;
case MessageType.Warning : Debug.LogWarning(Msg); break;
default : Debug.Log(Msg); break;
}
}
}
public static void ClearErrors()
{
GUI.FocusControl(null);
mLocalizationMsg = string.Empty;
}
#endregion
#region Unity Version branching
public static string Editor_GetCurrentScene()
{
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
return EditorApplication.currentScene;
#else
return SceneManager.GetActiveScene().path;
#endif
}
public static void Editor_MarkSceneDirty()
{
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
#else
EditorApplication.MarkSceneDirty();
#endif
}
public static void Editor_SaveScene(bool force=false)
{
if (force)
Editor_MarkSceneDirty();
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
EditorApplication.SaveScene ();
#else
EditorSceneManager.SaveOpenScenes();
#endif
}
public static void Editor_OpenScene( string sceneName )
{
#if UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
if (string.IsNullOrEmpty(sceneName))
EditorApplication.NewEmptyScene();
else
EditorApplication.OpenScene(sceneName);
#else
if (string.IsNullOrEmpty(sceneName))
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
else
EditorSceneManager.OpenScene(sceneName);
#endif
}
#endregion
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ffd53aaaf6936407d8b087583b0626e9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More