更新demo

更新demo
This commit is contained in:
ALEXTANG
2024-03-18 15:35:15 +08:00
parent 17a5d7425c
commit a2255b80cd
1028 changed files with 55353 additions and 35278 deletions

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 35f73e157d689ae44916c45f74a3370c
guid: 736bc06e2873e08418fef3194a34eeaf
SpriteAtlasImporter:
externalObjects: {}
userData:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ed51a84131b222945851b7ed062197da
guid: 30b2151baa80324468b12076c6025e5c
SpriteAtlasImporter:
externalObjects: {}
userData:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e409725293d95d84aa5e0c943054a97d
guid: 7180c75b26a0aa046b5743fbddb78c45
SpriteAtlasImporter:
externalObjects: {}
userData:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 46f2b6a7c8d6e534b9c57f91f44c3208
guid: d6c291e122fdd1b4f8338aa5a955cc67
SpriteAtlasImporter:
externalObjects: {}
userData:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 13eb6f2a63536ec49861839bfabae5b5
guid: acf10131b937dab4c86d63939aecd2ab
SpriteAtlasImporter:
externalObjects: {}
userData:

View File

@@ -28,6 +28,7 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4142826567245113224}
m_RootOrder: 0
@@ -60,6 +61,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@@ -102,6 +104,7 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4142826567245113224}
m_RootOrder: 1
@@ -134,6 +137,7 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
@@ -180,6 +184,7 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2380612195453094903}
- {fileID: 6184545274827739511}
@@ -228,4 +233,4 @@ MonoBehaviour:
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Bits: 55

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2de5a58f37a4ae64e804f150144da809
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: a363de58f5d6e9e438b2b9a692187f6e
guid: f069f2f03dfa55843a74dedc551eefb2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000

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

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d21fceb7ec2e3e04ab967b9273644e57
guid: 02e23552959dc0e4eaf254fd6c5c21bf
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -25,7 +25,7 @@ public class EntityAsteroid : MonoBehaviour
if (name.StartsWith("player"))
{
GameEvent.Send(ActorEventDefine.AsteroidExplosion,this.transform.position, this.transform.rotation);
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
void OnTriggerExit(Collider other)
@@ -33,7 +33,7 @@ public class EntityAsteroid : MonoBehaviour
var name = other.gameObject.name;
if (name.StartsWith("Boundary"))
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
}

View File

@@ -1,3 +1,4 @@
using GameLogic;
using TEngine;
using UnityEngine;
@@ -28,7 +29,7 @@ public class EntityBullet : MonoBehaviour
{
if (name.StartsWith("enemy") == false)
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
@@ -36,7 +37,7 @@ public class EntityBullet : MonoBehaviour
{
if (name.StartsWith("player") == false)
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
}
@@ -45,7 +46,7 @@ public class EntityBullet : MonoBehaviour
var name = other.gameObject.name;
if (name.StartsWith("Boundary"))
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
}

View File

@@ -1,4 +1,5 @@
using TEngine;
using GameLogic;
using TEngine;
using UnityEngine;
public class EntityEffect : MonoBehaviour
@@ -11,6 +12,6 @@ public class EntityEffect : MonoBehaviour
}
private void DelayDestroy()
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}

View File

@@ -69,7 +69,7 @@ public class EntityEnemy : MonoBehaviour
if (name.StartsWith("player"))
{
GameEvent.Send(ActorEventDefine.EnemyDead,this.transform.position, this.transform.rotation);
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
void OnTriggerExit(Collider other)
@@ -77,7 +77,7 @@ public class EntityEnemy : MonoBehaviour
var name = other.gameObject.name;
if (name.StartsWith("Boundary"))
{
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}

View File

@@ -51,7 +51,7 @@ public class EntityPlayer : MonoBehaviour
if (name.StartsWith("enemy") || name.StartsWith("asteroid"))
{
GameEvent.Send(ActorEventDefine.PlayerDead,transform.position, transform.rotation);
GameModule.Resource.FreeGameObject(this.gameObject);
PoolManager.Instance.PushGameObject(this.gameObject);
}
}
}

View File

@@ -11,239 +11,241 @@ using Random = UnityEngine.Random;
/// 战斗房间
/// </summary>
[Update]
public class BattleSystem:BehaviourSingleton<BattleSystem>
public class BattleSystem : BehaviourSingleton<BattleSystem>
{
private enum ESteps
{
None,
Ready,
Spawn,
WaitSpawn,
WaitWave,
GameOver,
}
private enum ESteps
{
None,
Ready,
Spawn,
WaitSpawn,
WaitWave,
GameOver,
}
private GameObject _roomRoot;
private GameObject _roomRoot;
// 关卡参数
private const int EnemyCount = 10;
private const int EnemyScore = 10;
private const int AsteroidScore = 1;
private readonly Vector3 _spawnValues = new Vector3(6, 0, 20);
private readonly string[] _entityLocations = new string[]
{
"asteroid01", "asteroid02", "asteroid03", "enemy_ship"
};
// 关卡参数
private const int EnemyCount = 10;
private const int EnemyScore = 10;
private const int AsteroidScore = 1;
private readonly Vector3 _spawnValues = new Vector3(6, 0, 20);
private ESteps _steps = ESteps.None;
private int _totalScore = 0;
private int _waveSpawnCount = 0;
//
// private UniTimer _startWaitTimer = UniTimer.CreateOnceTimer(1f);
// private UniTimer _spawnWaitTimer = UniTimer.CreateOnceTimer(0.75f);
// private UniTimer _waveWaitTimer = UniTimer.CreateOnceTimer(4f);
private readonly string[] _entityLocations = new string[]
{
"asteroid01", "asteroid02", "asteroid03", "enemy_ship"
};
private float _startWaitTimer = 1f;
private float _spawnWaitTimer = 0.75f;
private float _waveWaitTimer = 4f;
private ESteps _steps = ESteps.None;
private int _totalScore = 0;
/// <summary>
/// 加载房间
/// </summary>
public async UniTaskVoid LoadRoom()
{
_startWaitTimer = 1f;
await UniTask.Yield();
// 创建房间根对象
_roomRoot = new GameObject("BattleRoom");
private int _waveSpawnCount = 0;
//
// private UniTimer _startWaitTimer = UniTimer.CreateOnceTimer(1f);
// private UniTimer _spawnWaitTimer = UniTimer.CreateOnceTimer(0.75f);
// private UniTimer _waveWaitTimer = UniTimer.CreateOnceTimer(4f);
// 加载背景音乐
GameModule.Audio.Play(AudioType.Music, "music_background", true);
private float _startWaitTimer = 1f;
private float _spawnWaitTimer = 0.75f;
private float _waveWaitTimer = 4f;
// 创建玩家实体对象
var handle = GameModule.Resource.LoadAsset<GameObject>("player_ship", _roomRoot.transform);
var entity = handle.GetComponent<EntityPlayer>();
/// <summary>
/// 加载房间
/// </summary>
public async UniTaskVoid LoadRoom()
{
_startWaitTimer = 1f;
// 显示战斗界面
GameModule.UI.ShowUIAsync<UIBattleWindow>();
await UniTask.Yield();
// 创建房间根对象
_roomRoot = new GameObject("BattleRoom");
// 监听游戏事件
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerDead,OnPlayerDead);
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyDead,OnEnemyDead);
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.AsteroidExplosion,OnAsteroidExplosion);
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerFireBullet,OnPlayerFireBullet);
GameEvent.AddEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyFireBullet,OnEnemyFireBullet);
// 加载背景音乐
GameModule.Audio.Play(AudioType.Music, "music_background", true);
_steps = ESteps.Ready;
}
/// <summary>
/// 销毁房间
/// </summary>
public void DestroyRoom()
{
// 加载背景音乐
GameModule.Audio.Stop(AudioType.Music, true);
// 创建玩家实体对象
var handle = PoolManager.Instance.GetGameObject("player_ship",parent: _roomRoot.transform);
var entity = handle.GetComponent<EntityPlayer>();
// if (_entitySpawner != null)
// {
// _entitySpawner.DestroyAll(true);
// }
// 显示战斗界面
GameModule.UI.ShowUIAsync<UIBattleWindow>();
if (_roomRoot != null)
Object.Destroy(_roomRoot);
// 监听游戏事件
GameEvent.AddEventListener<Vector3, Quaternion>(ActorEventDefine.PlayerDead, OnPlayerDead);
GameEvent.AddEventListener<Vector3, Quaternion>(ActorEventDefine.EnemyDead, OnEnemyDead);
GameEvent.AddEventListener<Vector3, Quaternion>(ActorEventDefine.AsteroidExplosion, OnAsteroidExplosion);
GameEvent.AddEventListener<Vector3, Quaternion>(ActorEventDefine.PlayerFireBullet, OnPlayerFireBullet);
GameEvent.AddEventListener<Vector3, Quaternion>(ActorEventDefine.EnemyFireBullet, OnEnemyFireBullet);
GameModule.UI.CloseWindow<UIBattleWindow>();
// 监听游戏事件
GameEvent.RemoveEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerDead,OnPlayerDead);
GameEvent.RemoveEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyDead,OnEnemyDead);
GameEvent.RemoveEventListener<Vector3,Quaternion>(ActorEventDefine.AsteroidExplosion,OnAsteroidExplosion);
GameEvent.RemoveEventListener<Vector3,Quaternion>(ActorEventDefine.PlayerFireBullet,OnPlayerFireBullet);
GameEvent.RemoveEventListener<Vector3,Quaternion>(ActorEventDefine.EnemyFireBullet,OnEnemyFireBullet);
}
_steps = ESteps.Ready;
}
public override void Update()
{
UpdateRoom();
}
/// <summary>
/// 销毁房间
/// </summary>
public void DestroyRoom()
{
// 加载背景音乐
GameModule.Audio.Stop(AudioType.Music, true);
/// <summary>
/// 更新房间
/// </summary>
public void UpdateRoom()
{
if (_steps == ESteps.None || _steps == ESteps.GameOver)
return;
// if (_entitySpawner != null)
// {
// _entitySpawner.DestroyAll(true);
// }
if (_steps == ESteps.Ready)
{
_startWaitTimer -= Time.deltaTime;
if (_startWaitTimer <= 0)
{
_steps = ESteps.Spawn;
}
}
if (_roomRoot != null)
Object.Destroy(_roomRoot);
if (_steps == ESteps.Spawn)
{
var enemyLocation = _entityLocations[Random.Range(0, 4)];
Vector3 spawnPosition = new Vector3(Random.Range(-_spawnValues.x, _spawnValues.x), _spawnValues.y, _spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
GameModule.UI.CloseUI<UIBattleWindow>();
if (enemyLocation == "enemy_ship")
{
// 生成敌人实体
var gameObject = GameModule.Resource.LoadAsset<GameObject>(enemyLocation, _roomRoot.transform);
gameObject.transform.position = spawnPosition;
gameObject.transform.rotation = spawnRotation;
var entity = gameObject.GetComponent<EntityEnemy>();
entity.InitEntity();
}
else
{
// 生成小行星实体
var gameObject = GameModule.Resource.LoadAsset<GameObject>(enemyLocation, _roomRoot.transform);
gameObject.transform.position = spawnPosition;
gameObject.transform.rotation = spawnRotation;
var entity = gameObject.GetComponent<EntityAsteroid>();
entity.InitEntity();
}
// 监听游戏事件
GameEvent.RemoveEventListener<Vector3, Quaternion>(ActorEventDefine.PlayerDead, OnPlayerDead);
GameEvent.RemoveEventListener<Vector3, Quaternion>(ActorEventDefine.EnemyDead, OnEnemyDead);
GameEvent.RemoveEventListener<Vector3, Quaternion>(ActorEventDefine.AsteroidExplosion, OnAsteroidExplosion);
GameEvent.RemoveEventListener<Vector3, Quaternion>(ActorEventDefine.PlayerFireBullet, OnPlayerFireBullet);
GameEvent.RemoveEventListener<Vector3, Quaternion>(ActorEventDefine.EnemyFireBullet, OnEnemyFireBullet);
}
_waveSpawnCount++;
if (_waveSpawnCount >= EnemyCount)
{
_steps = ESteps.WaitWave;
}
else
{
_steps = ESteps.WaitSpawn;
}
}
public override void Update()
{
UpdateRoom();
}
if (_steps == ESteps.WaitSpawn)
{
_spawnWaitTimer -= Time.deltaTime;
if (_spawnWaitTimer <= 0)
{
_spawnWaitTimer = 0.75f;
_steps = ESteps.Spawn;
}
}
/// <summary>
/// 更新房间
/// </summary>
public void UpdateRoom()
{
if (_steps == ESteps.None || _steps == ESteps.GameOver)
return;
if (_steps == ESteps.WaitWave)
{
_waveWaitTimer -= Time.deltaTime;
if (_waveWaitTimer <= 0)
{
_waveWaitTimer = 4f;
_waveSpawnCount = 0;
_steps = ESteps.Spawn;
}
}
}
if (_steps == ESteps.Ready)
{
_startWaitTimer -= Time.deltaTime;
if (_startWaitTimer <= 0)
{
_steps = ESteps.Spawn;
}
}
if (_steps == ESteps.Spawn)
{
var enemyLocation = _entityLocations[Random.Range(0, 4)];
Vector3 spawnPosition = new Vector3(Random.Range(-_spawnValues.x, _spawnValues.x), _spawnValues.y, _spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
if (enemyLocation == "enemy_ship")
{
// 生成敌人实体
var gameObject = PoolManager.Instance.GetGameObject(enemyLocation,parent: _roomRoot.transform);
gameObject.transform.position = spawnPosition;
gameObject.transform.rotation = spawnRotation;
var entity = gameObject.GetComponent<EntityEnemy>();
entity.InitEntity();
}
else
{
// 生成小行星实体
var gameObject = PoolManager.Instance.GetGameObject(enemyLocation,parent: _roomRoot.transform);
gameObject.transform.position = spawnPosition;
gameObject.transform.rotation = spawnRotation;
var entity = gameObject.GetComponent<EntityAsteroid>();
entity.InitEntity();
}
_waveSpawnCount++;
if (_waveSpawnCount >= EnemyCount)
{
_steps = ESteps.WaitWave;
}
else
{
_steps = ESteps.WaitSpawn;
}
}
if (_steps == ESteps.WaitSpawn)
{
_spawnWaitTimer -= Time.deltaTime;
if (_spawnWaitTimer <= 0)
{
_spawnWaitTimer = 0.75f;
_steps = ESteps.Spawn;
}
}
if (_steps == ESteps.WaitWave)
{
_waveWaitTimer -= Time.deltaTime;
if (_waveWaitTimer <= 0)
{
_waveWaitTimer = 4f;
_waveSpawnCount = 0;
_steps = ESteps.Spawn;
}
}
}
#region
#region
private void OnPlayerDead(Vector3 position,Quaternion rotation)
{
// 创建爆炸效果
var gameObject = GameModule.Resource.LoadAsset<GameObject>("explosion_player", _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
_steps = ESteps.GameOver;
GameEvent.Send(ActorEventDefine.GameOver);
}
private void OnPlayerDead(Vector3 position, Quaternion rotation)
{
// 创建爆炸效果
var gameObject = PoolManager.Instance.GetGameObject("explosion_player",parent: _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
_steps = ESteps.GameOver;
GameEvent.Send(ActorEventDefine.GameOver);
}
private void OnEnemyDead(Vector3 position,Quaternion rotation)
{
// 创建爆炸效果
var gameObject = GameModule.Resource.LoadAsset<GameObject>("explosion_enemy", _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
private void OnEnemyDead(Vector3 position, Quaternion rotation)
{
// 创建爆炸效果
var gameObject = PoolManager.Instance.GetGameObject("explosion_enemy",parent: _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
_totalScore += EnemyScore;
GameEvent.Send(ActorEventDefine.ScoreChange,_totalScore);
}
_totalScore += EnemyScore;
GameEvent.Send(ActorEventDefine.ScoreChange, _totalScore);
}
private void OnAsteroidExplosion(Vector3 position,Quaternion rotation)
{
// 创建爆炸效果
var gameObject = GameModule.Resource.LoadAsset<GameObject>("explosion_asteroid", _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
private void OnAsteroidExplosion(Vector3 position, Quaternion rotation)
{
// 创建爆炸效果
var gameObject = PoolManager.Instance.GetGameObject("explosion_asteroid",parent: _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityEffect>();
entity.InitEntity();
_totalScore += AsteroidScore;
GameEvent.Send(ActorEventDefine.ScoreChange,_totalScore);
}
_totalScore += AsteroidScore;
GameEvent.Send(ActorEventDefine.ScoreChange, _totalScore);
}
private void OnPlayerFireBullet(Vector3 position,Quaternion rotation)
{
// 创建子弹实体
var gameObject = GameModule.Resource.LoadAsset<GameObject>("player_bullet", _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityBullet>();
entity.InitEntity();
}
private void OnEnemyFireBullet(Vector3 position,Quaternion rotation)
{
// 创建子弹实体
var gameObject = GameModule.Resource.LoadAsset<GameObject>("enemy_bullet", _roomRoot.transform);
private void OnPlayerFireBullet(Vector3 position, Quaternion rotation)
{
// 创建子弹实体
var gameObject = PoolManager.Instance.GetGameObject("player_bullet",parent: _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityBullet>();
entity.InitEntity();
}
}
#endregion
private void OnEnemyFireBullet(Vector3 position, Quaternion rotation)
{
// 创建子弹实体
var gameObject = PoolManager.Instance.GetGameObject("enemy_bullet",parent: _roomRoot.transform);
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
var entity = gameObject.GetComponent<EntityBullet>();
entity.InitEntity();
}
#endregion
}

View File

@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using TEngine;
using UnityEngine;
namespace GameLogic
{
public class PoolManager : MonoBehaviour
{
private static PoolManager _instance;
public static PoolManager Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<PoolManager>();
}
if (_instance == null)
{
GameObject gameObject = new GameObject();
gameObject.name = nameof(PoolManager);
_instance = gameObject.AddComponent<PoolManager>();
_instance.poolRootObj = gameObject;
DontDestroyOnLoad(_instance);
}
return _instance;
}
}
[SerializeField] private GameObject poolRootObj;
public Dictionary<string, GameObjectPoolData> gameObjectPoolDic = new Dictionary<string, GameObjectPoolData>();
public Dictionary<string, ObjectPoolData> objectPoolDic = new Dictionary<string, ObjectPoolData>();
public GameObject GetGameObject(string assetName, Transform parent = null)
{
GameObject obj = null;
if (gameObjectPoolDic.TryGetValue(assetName, out var gameObjectPoolData) && gameObjectPoolData.poolQueue.Count > 0)
{
obj = gameObjectPoolData.GetObj(parent);
}
if (obj == null)
{
obj = GameModule.Resource.LoadGameObject(assetName, parent: parent);
obj.name = assetName;
}
return obj;
}
public void PushGameObject(GameObject obj)
{
string objName = obj.name;
if (gameObjectPoolDic.TryGetValue(objName, out var gameObjectPoolData))
{
gameObjectPoolData.PushObj(obj);
}
else
{
gameObjectPoolDic.Add(objName, new GameObjectPoolData(obj, poolRootObj));
}
}
public T GetObject<T>() where T : class, new()
{
return CheckObjectCache<T>() ? (T)objectPoolDic[typeof(T).FullName].GetObj() : new T();
}
public void PushObject(object obj)
{
string fullName = obj.GetType().FullName;
if (objectPoolDic.ContainsKey(fullName))
{
objectPoolDic[fullName].PushObj(obj);
}
else
{
objectPoolDic.Add(fullName, new ObjectPoolData(obj));
}
}
private bool CheckObjectCache<T>()
{
string fullName = typeof(T).FullName;
return fullName != null && objectPoolDic.ContainsKey(fullName) && objectPoolDic[fullName].poolQueue.Count > 0;
}
public void Clear(bool clearGameObject = true, bool clearCObject = true)
{
if (clearGameObject)
{
for (int index = 0; index < poolRootObj.transform.childCount; ++index)
{
Destroy(poolRootObj.transform.GetChild(index).gameObject);
}
gameObjectPoolDic.Clear();
}
if (!clearCObject)
{
return;
}
objectPoolDic.Clear();
}
public void ClearAllGameObject() => Clear(clearCObject: false);
public void ClearGameObject(string prefabName)
{
GameObject obj = poolRootObj.transform.Find(prefabName).gameObject;
if (obj == null)
{
return;
}
Destroy(obj);
gameObjectPoolDic.Remove(prefabName);
}
public void ClearGameObject(GameObject prefab) => ClearGameObject(prefab.name);
public void ClearAllObject() => Clear(false);
public void ClearObject<T>() => objectPoolDic.Remove(typeof(T).FullName);
public void ClearObject(Type type) => objectPoolDic.Remove(type.FullName);
}
public class ObjectPoolData
{
public readonly Queue<object> poolQueue = new Queue<object>();
public ObjectPoolData(object obj) => PushObj(obj);
public void PushObj(object obj) => poolQueue.Enqueue(obj);
public object GetObj() => poolQueue.Dequeue();
}
public class GameObjectPoolData
{
public readonly GameObject fatherObj;
public readonly Queue<GameObject> poolQueue;
public GameObjectPoolData(GameObject obj, GameObject poolRootObj)
{
fatherObj = new GameObject(obj.name);
fatherObj.transform.SetParent(poolRootObj.transform);
poolQueue = new Queue<GameObject>();
PushObj(obj);
}
public GameObjectPoolData(GameObject fatherObj)
{
this.fatherObj = fatherObj;
}
public void PushObj(GameObject obj)
{
poolQueue.Enqueue(obj);
obj.transform.SetParent(fatherObj.transform);
obj.SetActive(false);
}
public GameObject GetObj(Transform parent = null)
{
GameObject go = poolQueue.Dequeue();
go.SetActive(true);
go.transform.SetParent(parent);
if (parent == null)
{
UnityEngine.SceneManagement.SceneManager.MoveGameObjectToScene(go, UnityEngine.SceneManagement.SceneManager.GetActiveScene());
}
return go;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6793af44177448799777835de5cc4a53
timeCreated: 1710746480

View File

@@ -15,7 +15,7 @@ namespace GameLogic
private Button m_btnRestart;
private Button m_btnHome;
public override void ScriptGenerator()
protected override void ScriptGenerator()
{
m_textScore = FindChildComponent<Text>("ScoreView/m_textScore");
m_goOverView = FindChild("m_goOverView").gameObject;
@@ -27,13 +27,13 @@ namespace GameLogic
#endregion
public override void RegisterEvent()
protected override void RegisterEvent()
{
AddUIEvent<int>(ActorEventDefine.ScoreChange, OnScoreChange);
AddUIEvent(ActorEventDefine.GameOver, OnGameOver);
}
public override void OnRefresh()
protected override void OnRefresh()
{
m_textScore.text = "Score : 0";
m_goOverView.SetActive(false);

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Reflection;
using Cysharp.Threading.Tasks;
using GameBase;
using GameLogic;
using TEngine;
/// <summary>

View File

@@ -3,13 +3,11 @@
"rootNamespace": "GameLogic",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:15fc0a57446b3144c949da3e2b9737a9",
"GUID:cbb0d51b565003841ae81cdbaf747114",
"GUID:8f58f15387c7a6f4fad9857024eb47f7",
"GUID:24c092aee38482f4e80715eaa8148782",
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:2b91a2c0e3055f54a8aab905c4163009"
"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

@@ -29,94 +29,113 @@ namespace GameMain
private async UniTaskVoid InitPackage(ProcedureOwner procedureOwner)
{
if (GameModule.Resource.PlayMode == EPlayMode.HostPlayMode ||
GameModule.Resource.PlayMode == EPlayMode.WebPlayMode)
try
{
if (SettingsUtils.EnableUpdateData())
if (GameModule.Resource.PlayMode == EPlayMode.HostPlayMode ||
GameModule.Resource.PlayMode == EPlayMode.WebPlayMode)
{
UpdateData updateData = await RequestUpdateData();
if (updateData != null)
if (SettingsUtils.EnableUpdateData())
{
if (!string.IsNullOrEmpty(updateData.HostServerURL))
{
SettingsUtils.FrameworkGlobalSettings.HostServerURL = updateData.HostServerURL;
}
UpdateData updateData = await RequestUpdateData();
if (!string.IsNullOrEmpty(updateData.FallbackHostServerURL))
if (updateData != null)
{
SettingsUtils.FrameworkGlobalSettings.FallbackHostServerURL =
updateData.FallbackHostServerURL;
if (!string.IsNullOrEmpty(updateData.HostServerURL))
{
SettingsUtils.FrameworkGlobalSettings.HostServerURL = updateData.HostServerURL;
}
if (!string.IsNullOrEmpty(updateData.FallbackHostServerURL))
{
SettingsUtils.FrameworkGlobalSettings.FallbackHostServerURL =
updateData.FallbackHostServerURL;
}
}
}
}
}
var initializationOperation = GameModule.Resource.InitPackage();
var initializationOperation = await GameModule.Resource.InitPackage();
await UniTask.Delay(TimeSpan.FromSeconds(1f));
await initializationOperation.ToUniTask();
if (initializationOperation.Status == EOperationStatus.Succeed)
{
//热更新阶段文本初始化
LoadText.Instance.InitConfigData(null);
GameEvent.Send(RuntimeId.ToRuntimeId("RefreshVersion"));
EPlayMode playMode = GameModule.Resource.PlayMode;
// 编辑器模式。
if (playMode == EPlayMode.EditorSimulateMode)
if (initializationOperation.Status == EOperationStatus.Succeed)
{
Log.Info("Editor resource mode detected.");
ChangeState<ProcedurePreload>(procedureOwner);
//热更新阶段文本初始化
LoadText.Instance.InitConfigData(null);
GameEvent.Send(RuntimeId.ToRuntimeId("RefreshVersion"));
EPlayMode playMode = GameModule.Resource.PlayMode;
// 编辑器模式。
if (playMode == EPlayMode.EditorSimulateMode)
{
Log.Info("Editor resource mode detected.");
ChangeState<ProcedurePreload>(procedureOwner);
}
// 单机模式。
else if (playMode == EPlayMode.OfflinePlayMode)
{
Log.Info("Package resource mode detected.");
ChangeState<ProcedureInitResources>(procedureOwner);
}
// 可更新模式。
else if (playMode == EPlayMode.HostPlayMode)
{
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate);
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???");
}
}
// 单机模式。
else if (playMode == EPlayMode.OfflinePlayMode)
{
Log.Info("Package resource mode detected.");
ChangeState<ProcedureInitResources>(procedureOwner);
}
// 可更新模式。
else if (playMode == EPlayMode.HostPlayMode)
else
{
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate);
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???");
Log.Error($"{initializationOperation.Error}");
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate, $"资源初始化失败!");
UILoadTip.ShowMessageBox(
$"资源初始化失败!点击确认重试 \n \n <color=#FF0000>原因{initializationOperation.Error}</color>",
MessageShowType.TwoButton,
LoadStyle.StyleEnum.Style_Retry
, () => { Retry(procedureOwner); }, UnityEngine.Application.Quit);
}
}
else
catch (Exception e)
{
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate);
Log.Error($"{initializationOperation.Error}");
// 打开启动UI。
UILoadMgr.Show(UIDefine.UILoadUpdate, $"资源初始化失败!");
UILoadTip.ShowMessageBox(
$"资源初始化失败!点击确认重试 \n \n <color=#FF0000>原因{initializationOperation.Error}</color>",
MessageShowType.TwoButton,
LoadStyle.StyleEnum.Style_Retry
, () => { Retry(procedureOwner); }, UnityEngine.Application.Quit);
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)
{
// 打开启动UI。

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;
@@ -141,6 +138,7 @@ namespace GameMain
private Assembly GetMainLogicAssembly()
{
m_HotfixAssemblys.Clear();
Assembly mainLogicAssembly = null;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
@@ -170,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);
@@ -204,7 +201,7 @@ namespace GameMain
{
m_LoadAssemblyComplete = m_LoadAssemblyWait && 0 == m_LoadAssetCount;
}
assetOperationHandle.Dispose();
GameModule.Resource.UnloadAsset(textAsset);
}
/// <summary>
@@ -238,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;
}
@@ -246,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)
@@ -278,8 +277,8 @@ namespace GameMain
finally
{
m_LoadMetadataAssemblyComplete = m_LoadMetadataAssemblyWait && 0 == m_LoadMetadataAssetCount;
}
GameModule.Resource.UnloadAsset(textAsset);
}
}
}

View File

@@ -22,19 +22,24 @@ 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)
{
base.OnEnter(procedureOwner);
_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");
@@ -87,11 +92,6 @@ namespace GameMain
return;
}
if (_hadInitConfigXml == false)
{
return;
}
ChangeState<ProcedureLoadAssembly>(procedureOwner);
}
@@ -120,51 +120,44 @@ namespace GameMain
{
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)
{
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.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)
{
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

@@ -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,5 +1,5 @@
fileFormatVersion: 2
guid: 9f6e7416bb0867f4f8fa5da4d92e1d8d
guid: 98976375d413b9542acc4b0f2fba7195
folderAsset: yes
DefaultImporter:
externalObjects: {}

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"

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

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b763f43bfb633944aa8955535b965c1f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

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

@@ -10,9 +10,7 @@ public static class SyncAssemblyContent
{
SettingsUtils.SetHybridCLRHotUpdateAssemblies(HybridCLR.Editor.SettingsUtil.HotUpdateAssemblyFilesIncludePreserved);
SettingsUtils.SetHybridCLRAOTMetaAssemblies(HybridCLR.Editor.SettingsUtil.AOTAssemblyNames);
SettingsUtils.HybridCLRCustomGlobalSettings.Enable = HybridCLR.Editor.SettingsUtil.Enable;
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
Debug.Log("同步AOT和HotUpdate程序集 HybridCLR到TEngineSettings成功。");
}
}

View File

@@ -1,12 +1,24 @@
#if ENABLE_HYBRIDCLR
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
#endif
using TEngine.Editor;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class BuildDLLCommand
{
private const string EnableHybridClrScriptingDefineSymbol = "ENABLE_HYBRIDCLR";
static BuildDLLCommand()
{
#if ENABLE_HYBRIDCLR
HybridCLR.Editor.SettingsUtil.Enable = true;
#else
HybridCLR.Editor.SettingsUtil.Enable = false;
#endif
}
/// <summary>
/// 禁用HybridCLR宏定义。
@@ -15,6 +27,8 @@ public static class BuildDLLCommand
public static void Disable()
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableHybridClrScriptingDefineSymbol);
HybridCLR.Editor.SettingsUtil.Enable = false;
SyncAssemblyContent.RefreshAssembly();
}
/// <summary>
@@ -25,20 +39,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 +70,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 +87,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 +104,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
{
@@ -13,60 +8,35 @@ namespace TEngine.Editor.Inspector
{
private static readonly string[] _resourceModeNames = new string[]
{
"EditorSimulateMode (编辑器下的模拟模式)",
"OfflinePlayMode (单机模式)",
"HostPlayMode (联机运行模式)" ,
"EditorSimulateMode (编辑器下的模拟模式)",
"OfflinePlayMode (单机模式)",
"HostPlayMode (联机运行模式)",
"WebPlayMode (WebGL运行模式)"
};
private static readonly string[] _verifyLevelNames = new string[]
{
"Low (验证文件存在)",
"Middle (验证文件大小)",
"Low (验证文件存在)",
"Middle (验证文件大小)",
"High (验证文件大小和CRC)"
};
private SerializedProperty m_PackageName = null;
private SerializedProperty m_PlayMode = null;
private SerializedProperty m_ReadWritePathType = 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 +51,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,32 +68,6 @@ 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);
@@ -142,7 +79,7 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.milliseconds = milliseconds;
t.Milliseconds = milliseconds;
}
else
{
@@ -150,8 +87,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 +101,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 +120,7 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.downloadingMaxNum = (int)downloadingMaxNum;
t.DownloadingMaxNum = (int)downloadingMaxNum;
}
else
{
@@ -194,36 +133,77 @@ namespace TEngine.Editor.Inspector
{
if (EditorApplication.isPlaying)
{
t.failedTryAgain = (int)failedTryAgain;
t.FailedTryAgain = (int)failedTryAgain;
}
else
{
m_FailedTryAgain.intValue = (int)failedTryAgain;
}
}
int adaptiveReplacementCacheCapacity = (int)EditorGUILayout.Slider("ARC Table Capacity", m_adaptiveReplacementCacheCapacity.intValue, 8f, 128f);
if (adaptiveReplacementCacheCapacity != m_adaptiveReplacementCacheCapacity.intValue)
EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
{
if (EditorApplication.isPlaying)
float assetAutoReleaseInterval = EditorGUILayout.DelayedFloatField("Asset Auto Release Interval", m_AssetAutoReleaseInterval.floatValue);
if (Math.Abs(assetAutoReleaseInterval - m_AssetAutoReleaseInterval.floatValue) > 0.01f)
{
t.adaptiveReplacementCacheCapacity = adaptiveReplacementCacheCapacity;
if (EditorApplication.isPlaying)
{
t.AssetAutoReleaseInterval = assetAutoReleaseInterval;
}
else
{
m_AssetAutoReleaseInterval.floatValue = assetAutoReleaseInterval;
}
}
else
int assetCapacity = EditorGUILayout.DelayedIntField("Asset Capacity", m_AssetCapacity.intValue);
if (assetCapacity != m_AssetCapacity.intValue)
{
m_adaptiveReplacementCacheCapacity.intValue = adaptiveReplacementCacheCapacity;
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 +218,34 @@ namespace TEngine.Editor.Inspector
RefreshTypeNames();
}
private void OnEnable()
{
m_PlayMode = serializedObject.FindProperty("playMode");
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: 40c870edb8e84064a8be2d56acb8bbc0
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:

View File

@@ -0,0 +1,477 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
private List<string> mTranslationTerms = new List<string>();
private Dictionary<string, TranslationQuery> mTranslationRequests = new Dictionary<string, TranslationQuery> ();
private bool mAppNameTerm_Expanded;
private List<string> mLanguageCodePopupList;
#endregion
void OnGUI_Languages()
{
//GUILayout.Space(5);
OnGUI_ShowMsg();
OnGUI_LanguageList();
OnGUI_StoreIntegration();
GUILayout.BeginHorizontal();
GUILayout.Label(new GUIContent("On Missing Translation:", "What should happen IN-GAME when a term is not yet translated to the current language?"), EditorStyles.boldLabel, GUILayout.Width(200));
GUILayout.BeginVertical();
GUILayout.Space(7);
EditorGUILayout.PropertyField(mProp_OnMissingTranslation, GUITools.EmptyContent, GUILayout.Width(165));
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label(new GUIContent("Unload Languages At Runtime:", "When playing the game, the plugin will unload all unused languages and only load them when needed"), EditorStyles.boldLabel, GUILayout.Width(200));
GUILayout.BeginVertical();
GUILayout.Space(7);
EditorGUILayout.PropertyField(mProp_AllowUnloadingLanguages, GUITools.EmptyContent, GUILayout.Width(165));
GUILayout.EndVertical();
GUILayout.EndHorizontal();
string firstLanguage = "";
if (mLanguageSource.mLanguages.Count > 0)
firstLanguage = " (" + mLanguageSource.mLanguages [0].Name + ")";
GUILayout.BeginHorizontal();
GUILayout.Label(new GUIContent("Default Language:", "When the game starts this is the language that will be used until the player manually selects a language"), EditorStyles.boldLabel, GUILayout.Width(160));
GUILayout.BeginVertical();
GUILayout.Space(7);
mProp_IgnoreDeviceLanguage.boolValue = EditorGUILayout.Popup(mProp_IgnoreDeviceLanguage.boolValue?1:0, new[]{"Device Language", "First in List"+firstLanguage}, GUILayout.ExpandWidth(true))==1;
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
#region GUI Languages
void OnGUI_LanguageList()
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.FlexibleSpace();
GUILayout.Label ("Languages:", EditorStyles.miniLabel, GUILayout.ExpandWidth(false));
GUILayout.FlexibleSpace();
GUILayout.Label ("Code:", EditorStyles.miniLabel);
GUILayout.Space(170);
GUILayout.EndHorizontal();
//--[ Language List ]--------------------------
int IndexLanguageToDelete = -1;
int LanguageToMoveUp = -1;
int LanguageToMoveDown = -1;
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
mScrollPos_Languages = GUILayout.BeginScrollView( mScrollPos_Languages, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight (200), /*GUILayout.MaxHeight(Screen.height),*/ GUILayout.ExpandHeight(false));
GUI.backgroundColor = Color.white;
if (mLanguageCodePopupList == null || mLanguageCodePopupList.Count==0)
{
mLanguageCodePopupList = GoogleLanguages.GetLanguagesForDropdown("", "");
mLanguageCodePopupList.Sort();
mLanguageCodePopupList.Insert(0, string.Empty);
}
for (int i=0, imax=mProp_Languages.arraySize; i<imax; ++i)
{
SerializedProperty Prop_Lang = mProp_Languages.GetArrayElementAtIndex(i);
SerializedProperty Prop_LangName = Prop_Lang.FindPropertyRelative("Name");
SerializedProperty Prop_LangCode = Prop_Lang.FindPropertyRelative("Code");
SerializedProperty Prop_Flags = Prop_Lang.FindPropertyRelative("Flags");
bool isLanguageEnabled = (Prop_Flags.intValue & (int)eLanguageDataFlags.DISABLED)==0;
GUI.color = isLanguageEnabled ? Color.white : new Color(1, 1, 1, 0.3f);
GUILayout.BeginHorizontal();
if (GUILayout.Button ("X", "toolbarbutton", GUILayout.ExpandWidth(false)))
{
IndexLanguageToDelete = i;
}
GUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUI.BeginChangeCheck();
string LanName = EditorGUILayout.TextField(Prop_LangName.stringValue, GUILayout.ExpandWidth(true));
if (EditorGUI.EndChangeCheck() && !string.IsNullOrEmpty(LanName))
{
Prop_LangName.stringValue = LanName;
}
var currentCode = "[" + Prop_LangCode.stringValue + "]";
if (isLanguageEnabled)
{
int Index = Mathf.Max(0, mLanguageCodePopupList.FindIndex(c => c.Contains(currentCode)));
EditorGUI.BeginChangeCheck();
Index = EditorGUILayout.Popup(Index, mLanguageCodePopupList.ToArray(), EditorStyles.toolbarPopup, GUILayout.Width(60));
if (EditorGUI.EndChangeCheck() && Index >= 0)
{
currentCode = mLanguageCodePopupList[Index];
int i0 = currentCode.IndexOf("[");
int i1 = currentCode.IndexOf("]");
if (i0 >= 0 && i1 > i0)
Prop_LangCode.stringValue = currentCode.Substring(i0 + 1, i1 - i0 - 1);
else
Prop_LangCode.stringValue = string.Empty;
}
var rect = GUILayoutUtility.GetLastRect();
GUI.Label(rect, Prop_LangCode.stringValue, EditorStyles.toolbarPopup);
}
else
{
GUILayout.Label(Prop_LangCode.stringValue, EditorStyles.toolbarPopup, GUILayout.Width(60));
}
GUILayout.EndHorizontal();
GUI.enabled = i<imax-1;
if (GUILayout.Button( "\u25BC", EditorStyles.toolbarButton, GUILayout.Width(18))) LanguageToMoveDown = i;
GUI.enabled = i>0;
if (GUILayout.Button( "\u25B2", EditorStyles.toolbarButton, GUILayout.Width(18))) LanguageToMoveUp = i;
GUI.enabled = true;
if (GUILayout.Button( new GUIContent("Show", "Preview all localizations into this language"), EditorStyles.toolbarButton, GUILayout.Width(35)))
{
LocalizationManager.SetLanguageAndCode( LanName, Prop_LangCode.stringValue, false, true);
}
if (TestButtonArg( eTest_ActionType.Button_Languages_TranslateAll, i, new GUIContent("Translate", "Translate all empty terms"), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
GUITools.DelayedCall( () => TranslateAllToLanguage(LanName));
}
GUI.enabled = true;
GUI.color = Color.white;
EditorGUI.BeginChangeCheck();
isLanguageEnabled = EditorGUILayout.Toggle(isLanguageEnabled, GUILayout.Width(15));
var r = GUILayoutUtility.GetLastRect();
GUI.Label(r, new GUIContent("", "Enable/Disable the language.\nDisabled languages can be used to store data values or to avoid showing Languages that are stil under development"));
if (EditorGUI.EndChangeCheck())
{
Prop_Flags.intValue = (Prop_Flags.intValue & ~(int)eLanguageDataFlags.DISABLED) | (isLanguageEnabled ? 0 : (int)eLanguageDataFlags.DISABLED);
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
OnGUI_AddLanguage( mProp_Languages );
if (mConnection_WWW!=null || mConnection_Text.Contains("Translating"))
{
// Connection Status Bar
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
string Loading = mConnection_Text + ".....".Substring(0, time);
GUI.color = Color.gray;
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
GUILayout.Label (Loading, EditorStyles.miniLabel);
GUI.color = Color.white;
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
GoogleTranslation.CancelCurrentGoogleTranslations ();
StopConnectionWWW();
}
GUILayout.EndHorizontal();
Repaint();
}
if (IndexLanguageToDelete>=0)
{
if (EditorUtility.DisplayDialog ("Confirm delete", "Are you sure you want to delete the selected language", "Yes", "Cancel"))
{
mLanguageSource.RemoveLanguage (mLanguageSource.mLanguages [IndexLanguageToDelete].Name);
serializedObject.Update ();
ParseTerms (true, false, false);
}
}
if (LanguageToMoveUp>=0) SwapLanguages( LanguageToMoveUp, LanguageToMoveUp-1 );
if (LanguageToMoveDown>=0) SwapLanguages( LanguageToMoveDown, LanguageToMoveDown+1 );
}
void SwapLanguages( int iFirst, int iSecond )
{
serializedObject.ApplyModifiedProperties();
LanguageSourceData Source = mLanguageSource;
SwapValues( Source.mLanguages, iFirst, iSecond );
foreach (TermData termData in Source.mTerms)
{
SwapValues ( termData.Languages, iFirst, iSecond );
SwapValues ( termData.Flags, iFirst, iSecond );
}
serializedObject.Update();
}
void SwapValues( List<LanguageData> mList, int Index1, int Index2 )
{
LanguageData temp = mList[Index1];
mList[Index1] = mList[Index2];
mList[Index2] = temp;
}
void SwapValues( string[] mList, int Index1, int Index2 )
{
string temp = mList[Index1];
mList[Index1] = mList[Index2];
mList[Index2] = temp;
}
void SwapValues( byte[] mList, int Index1, int Index2 )
{
byte temp = mList[Index1];
mList[Index1] = mList[Index2];
mList[Index2] = temp;
}
void OnGUI_AddLanguage( SerializedProperty Prop_Languages)
{
//--[ Add Language Upper Toolbar ]-----------------
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.BeginHorizontal(EditorStyles.toolbar);
mLanguages_NewLanguage = EditorGUILayout.TextField("", mLanguages_NewLanguage, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
GUI.enabled = !string.IsNullOrEmpty (mLanguages_NewLanguage);
if (TestButton(eTest_ActionType.Button_AddLanguageManual,"Add", EditorStyles.toolbarButton, GUILayout.Width(50)))
{
Prop_Languages.serializedObject.ApplyModifiedProperties();
mLanguageSource.AddLanguage( mLanguages_NewLanguage, GoogleLanguages.GetLanguageCode(mLanguages_NewLanguage) );
Prop_Languages.serializedObject.Update();
mLanguages_NewLanguage = "";
GUI.FocusControl(string.Empty);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
//--[ Add Language Bottom Toolbar ]-----------------
GUILayout.BeginHorizontal();
//-- Language Dropdown -----------------
string CodesToExclude = string.Empty;
foreach (var LanData in mLanguageSource.mLanguages)
CodesToExclude = string.Concat(CodesToExclude, "[", LanData.Code, "]");
List<string> Languages = GoogleLanguages.GetLanguagesForDropdown(mLanguages_NewLanguage, CodesToExclude);
GUI.changed = false;
int index = EditorGUILayout.Popup(0, Languages.ToArray(), EditorStyles.toolbarDropDown);
if (GUI.changed && index>=0)
{
mLanguages_NewLanguage = GoogleLanguages.GetFormatedLanguageName( Languages[index] );
}
if (TestButton(eTest_ActionType.Button_AddLanguageFromPopup, "Add", EditorStyles.toolbarButton, GUILayout.Width(50)) && index>=0)
{
Prop_Languages.serializedObject.ApplyModifiedProperties();
mLanguages_NewLanguage = GoogleLanguages.GetFormatedLanguageName(Languages[index]);
if (!string.IsNullOrEmpty(mLanguages_NewLanguage))
mLanguageSource.AddLanguage(mLanguages_NewLanguage, GoogleLanguages.GetLanguageCode(mLanguages_NewLanguage));
Prop_Languages.serializedObject.Update();
mLanguages_NewLanguage = "";
GUI.FocusControl(string.Empty);
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUI.color = Color.white;
}
void TranslateAllToLanguage (string lanName)
{
if (!GoogleTranslation.CanTranslate ())
{
ShowError ("WebService is not set correctly or needs to be reinstalled");
return;
}
ClearErrors();
int LanIndex = mLanguageSource.GetLanguageIndex (lanName);
string code = mLanguageSource.mLanguages [LanIndex].Code;
string googleCode = GoogleLanguages.GetGoogleLanguageCode(code);
if (string.IsNullOrEmpty(googleCode))
{
ShowError("Language '" + code + "' is not supported by google translate");
return;
}
googleCode = code;
mTranslationTerms.Clear ();
mTranslationRequests.Clear ();
foreach (var termData in mLanguageSource.mTerms)
{
if (termData.TermType != eTermType.Text)
continue;
if (!string.IsNullOrEmpty(termData.Languages[LanIndex]))
continue;
string sourceCode, sourceText;
FindTranslationSource( LanguageSourceData.GetKeyFromFullTerm(termData.Term), termData, code, null, out sourceText, out sourceCode );
mTranslationTerms.Add (termData.Term);
GoogleTranslation.CreateQueries(sourceText, sourceCode, googleCode, mTranslationRequests); // can split plurals into several queries
}
if (mTranslationRequests.Count == 0)
{
StopConnectionWWW ();
return;
}
mConnection_WWW = null;
mConnection_Text = "Translating"; if (mTranslationRequests.Count > 1) mConnection_Text += " (" + mTranslationRequests.Count + ")";
mConnection_Callback = null;
//EditorApplication.update += CheckForConnection;
GoogleTranslation.Translate (mTranslationRequests, OnLanguageTranslated);
}
void OnLanguageTranslated( Dictionary<string, TranslationQuery> requests, string Error )
{
//Debug.Log (Result);
//if (Result.Contains("Service invoked too many times"))
//{
// TimeStartTranslation = EditorApplication.timeSinceStartup + 1;
// EditorApplication.update += DelayedStartTranslation;
// mConnection_Text = "Translating (" + mTranslationRequests.Count + ")";
// return;
//}
//if (!string.IsNullOrEmpty(Error))/* || !Result.Contains("<i2>")*/
//{
// Debug.LogError("WEB ERROR: " + Error);
// ShowError ("Unable to access Google or not valid request");
// return;
//}
ClearErrors();
StopConnectionWWW();
if (!string.IsNullOrEmpty(Error))
{
ShowError (Error);
return;
}
if (requests.Values.Count == 0)
return;
var langCode = requests.Values.First().TargetLanguagesCode [0];
//langCode = GoogleLanguages.GetGoogleLanguageCode(langCode);
int langIndex = mLanguageSource.GetLanguageIndexFromCode (langCode, false);
//if (langIndex >= 0)
{
foreach (var term in mTranslationTerms)
{
var termData = mLanguageSource.GetTermData(term);
if (termData == null)
continue;
if (termData.TermType != eTermType.Text)
continue;
//if (termData.Languages.Length <= langIndex)
// continue;
string sourceCode, sourceText;
FindTranslationSource(LanguageSourceData.GetKeyFromFullTerm(termData.Term), termData, langCode, null, out sourceText, out sourceCode);
string result = GoogleTranslation.RebuildTranslation(sourceText, mTranslationRequests, langCode); // gets the result from google and rebuilds the text from multiple queries if its is plurals
termData.Languages[langIndex] = result;
}
}
mTranslationTerms.Clear ();
mTranslationRequests.Clear ();
StopConnectionWWW ();
}
#endregion
#region Store Integration
void OnGUI_StoreIntegration()
{
GUIStyle lstyle = new GUIStyle (EditorStyles.label);
lstyle.richText = true;
GUILayout.BeginHorizontal ();
GUILayout.Label (new GUIContent("Store Integration:", "Setups the stores to detect that the game has localization, Android adds strings.xml for each language. IOS modifies the Info.plist"), EditorStyles.boldLabel, GUILayout.Width(160));
GUILayout.FlexibleSpace();
GUILayout.Label( new GUIContent( "<color=green><size=16>\u2713</size></color> IOS", "Setups the stores to show in iTunes and the Appstore all the languages that this app supports, also localizes the app name if available" ), lstyle, GUILayout.Width( 90 ) );
GUILayout.Label( new GUIContent( "<color=green><size=16>\u2713</size></color> Android", "Setups the stores to show in GooglePlay all the languages this app supports, also localizes the app name if available" ), lstyle, GUILayout.Width( 90 ) );
GUILayout.EndHorizontal ();
GUILayout.BeginHorizontal();
mAppNameTerm_Expanded = GUILayout.Toggle(mAppNameTerm_Expanded, new GUIContent( "App Name translations:", "How should the game be named in the devices based on their language" ), EditorStyles.foldout, GUILayout.Width( 160 ) );
GUILayout.Label("", GUILayout.ExpandWidth(true));
var rect = GUILayoutUtility.GetLastRect();
TermsPopup_Drawer.ShowGUI( rect, mProp_AppNameTerm, GUITools.EmptyContent, mLanguageSource);
if (GUILayout.Button("New Term", EditorStyles.miniButton, GUILayout.ExpandWidth(false)))
{
AddLocalTerm("App_Name");
mProp_AppNameTerm.stringValue = "App_Name";
mAppNameTerm_Expanded = true;
}
GUILayout.EndHorizontal();
if (mAppNameTerm_Expanded)
{
GUILayout.BeginHorizontal();
GUILayout.Space(10);
GUILayout.BeginVertical("Box");
var termName = mProp_AppNameTerm.stringValue;
if (!string.IsNullOrEmpty(termName))
{
var termData = LocalizationManager.GetTermData(termName);
if (termData != null)
OnGUI_Keys_Languages(mProp_AppNameTerm.stringValue, ref termData, null, true, mLanguageSource);
}
GUILayout.Space(10);
GUILayout.BeginHorizontal();
GUILayout.Label("<b>Default App Name:</b>", lstyle, GUITools.DontExpandWidth);
GUILayout.Label(Application.productName);
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,727 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using TEngine.Localization.SimpleJSON;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
public static Dictionary<string, string> mGoogleSpreadsheets = new Dictionary<string, string>(StringComparer.Ordinal);
public UnityWebRequest mConnection_WWW;
delegate void fnConnectionCallback(string Result, string Error);
event fnConnectionCallback mConnection_Callback;
//float mConnection_TimeOut;
string mConnection_Text = string.Empty;
string mWebService_Status;
#endregion
#region GUI
void OnGUI_Spreadsheet_Google()
{
GUILayout.Space(20);
#if UNITY_WEBPLAYER
mConnection_Text = string.Empty;
EditorGUILayout.HelpBox("Google Synchronization is not supported when in WebPlayer mode." + mConnection_Text, MessageType.Info);
mProp_GoogleUpdateFrequency.enumValueIndex = mProp_GoogleUpdateFrequency.enumValueIndex; // to avoid the warning "unused"
mProp_GoogleUpdateSynchronization.enumValueIndex = mProp_GoogleUpdateSynchronization.enumValueIndex;
#else
OnGUI_GoogleCredentials();
OnGUI_ShowMsg();
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
return;
if (mWebService_Status == "Offline")
return;
GUILayout.Space(20);
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height (1));
GUI.backgroundColor = Color.white;
GUILayout.Space(10);
GUILayout.BeginHorizontal();
GUILayout.Label(new GUIContent(" Password", "This should match the value of the LocalizationPassword variable in the WebService Script in your Google Drive"), GUILayout.Width(108));
mProp_Google_Password.stringValue = EditorGUILayout.TextField(mProp_Google_Password.stringValue, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
OnGUI_GoogleSpreadsheetsInGDrive();
GUILayout.EndVertical();
if (mConnection_WWW!=null)
{
// Connection Status Bar
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
string Loading = mConnection_Text + ".....".Substring(0, time);
GUI.color = Color.gray;
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
GUILayout.Label (Loading, EditorStyles.miniLabel);
GUI.color = Color.white;
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
StopConnectionWWW();
GUILayout.EndHorizontal();
Repaint();
}
//else
// GUILayout.Space(10);
EditorGUI.BeginChangeCheck();
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
LanguageSourceData.eGoogleUpdateFrequency GoogleUpdateFrequency = (LanguageSourceData.eGoogleUpdateFrequency)mProp_GoogleUpdateFrequency.enumValueIndex;
GoogleUpdateFrequency = (LanguageSourceData.eGoogleUpdateFrequency)EditorGUILayout.EnumPopup("Auto Update Frequency", GoogleUpdateFrequency, GUILayout.ExpandWidth(true));
if (EditorGUI.EndChangeCheck())
{
mProp_GoogleUpdateFrequency.enumValueIndex = (int)GoogleUpdateFrequency;
}
GUILayout.Space(10);
GUILayout.Label("Delay:");
mProp_GoogleUpdateDelay.floatValue = EditorGUILayout.FloatField(mProp_GoogleUpdateDelay.floatValue, GUILayout.Width(30));
GUILayout.Label("secs");
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
var GoogleInEditorCheckFrequency = (LanguageSourceData.eGoogleUpdateFrequency)mProp_GoogleInEditorCheckFrequency.enumValueIndex;
EditorGUI.BeginChangeCheck();
GoogleInEditorCheckFrequency = (LanguageSourceData.eGoogleUpdateFrequency)EditorGUILayout.EnumPopup(new GUIContent("In-Editor Check Frequency", "How often the editor will verify that the Spreadsheet is up-to-date with the LanguageSource. Having un-synchronized Spreadsheets can lead to issues when playing in the device as the download data will override the one in the build"), GoogleInEditorCheckFrequency, GUILayout.ExpandWidth(false));
if (EditorGUI.EndChangeCheck())
{
mProp_GoogleInEditorCheckFrequency.enumValueIndex = (int)GoogleInEditorCheckFrequency;
}
GUILayout.Space(122);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label("Update Synchronization", GUILayout.Width(180));
EditorGUI.BeginChangeCheck();
LanguageSourceData.eGoogleUpdateSynchronization GoogleUpdateSynchronization = (LanguageSourceData.eGoogleUpdateSynchronization)mProp_GoogleUpdateSynchronization.enumValueIndex;
GoogleUpdateSynchronization = (LanguageSourceData.eGoogleUpdateSynchronization)EditorGUILayout.EnumPopup(GoogleUpdateSynchronization, GUILayout.Width(178));
if (EditorGUI.EndChangeCheck())
{
mProp_GoogleUpdateSynchronization.enumValueIndex = (int)GoogleUpdateSynchronization;
}
GUILayout.EndHorizontal();
GUILayout.Space(5);
GUI.changed = false;
bool OpenDataSourceAfterExport = EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
OpenDataSourceAfterExport = GUILayout.Toggle(OpenDataSourceAfterExport, "Open Spreadsheet after Export");
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
if (GUI.changed)
{
GUI.changed = false;
EditorPrefs.SetBool("I2Loc OpenDataSourceAfterExport", OpenDataSourceAfterExport);
}
#endif
GUILayout.Space(5);
}
void OnGUI_GoogleCredentials()
{
GUI.enabled = mConnection_WWW==null;
GUI.changed = false;
string WebServiceHelp = "The web service is a script running on the google drive where the spreadsheet you want to use is located.\nThat script allows the game to synchronize the localization even after the game is published.";
GUILayout.BeginHorizontal();
GUILayout.Label (new GUIContent("Web Service URL:", WebServiceHelp), GUILayout.Width(110));
GUI.SetNextControlName ("WebServiceURL");
mProp_Google_WebServiceURL.stringValue = EditorGUILayout.TextField(mProp_Google_WebServiceURL.stringValue);
if (!string.IsNullOrEmpty(mWebService_Status))
{
if (mWebService_Status=="Online")
{
GUI.color = Color.green;
GUILayout.Label( "", GUILayout.Width(17));
Rect r = GUILayoutUtility.GetLastRect(); r.xMin += 3; r.yMin-= 3; r.xMax+= 2; r.yMax+=2;
GUI.Label( r, new GUIContent("\u2713", "Online"), EditorStyles.whiteLargeLabel);
GUI.color = Color.white;
}
else
if (mWebService_Status=="Offline")
{
GUI.color = Color.red;
GUILayout.Label( "", GUILayout.Width(17));
Rect r = GUILayoutUtility.GetLastRect(); r.xMin += 3; r.yMin-= 3; r.xMax+= 2; r.yMax+=2;
GUI.Label( r, new GUIContent("\u2717", mWebService_Status), EditorStyles.whiteLargeLabel);
GUI.color = Color.white;
}
else
if (mWebService_Status=="UnsupportedVersion")
{
Rect rect = GUILayoutUtility.GetLastRect();
float Width = 15;
rect.xMin = rect.xMax+1;
rect.xMax = rect.xMin + rect.height;
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
GUI.Label(rect, new GUIContent("\u2717", "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version."));
GUILayout.Space (Width);
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Space (118);
if (GUILayout.Button(new GUIContent("Install", "This opens the Web Service Script and shows you steps to install and authorize it on your Google Drive"), EditorStyles.toolbarButton))
{
ClearErrors();
Application.OpenURL("https://script.google.com/d/1zcsLSmq3Oddd8AsLuoKNDG1Y0eYBOHzyvGT7v94u1oN6igmsZb_PJzEm/newcopy"); // V5
//Application.OpenURL("https://goo.gl/RBCO0o"); // V4:https://script.google.com/d/1T7e5_40NcgRyind-yeg4PAkHz9TNZJ22F4RcbOvCpAs03JNf1vKNNTZB/newcopy
//Application.OpenURL("https://goo.gl/wFSbv2");// V3:https://script.google.com/d/1CxQDSXflsXRaH3M7xGfrIDrFwOIHWPsYTWi4mRZ_k77nyIInTgIk63Kd/newcopy");
}
if (GUILayout.Button("Verify", EditorStyles.toolbarButton))
{
ClearErrors();
VerifyGoogleService(mProp_Google_WebServiceURL.stringValue);
GUI.changed = false;
}
GUILayout.EndHorizontal();
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
{
EditorGUILayout.HelpBox(WebServiceHelp, MessageType.Info);
}
if (GUI.changed)
{
if (string.IsNullOrEmpty(mProp_Google_WebServiceURL.stringValue))
{
mProp_Google_SpreadsheetKey.stringValue = string.Empty;
mProp_Google_SpreadsheetName.stringValue = string.Empty;
}
// If the web service changed then clear the cached spreadsheet keys
mGoogleSpreadsheets.Clear();
GUI.changed = false;
ClearErrors();
}
GUI.enabled = true;
}
void OnGUI_GoogleSpreadsheetsInGDrive()
{
GUI.enabled = mConnection_WWW==null;
string[] Spreadsheets;
string[] SpreadsheetsKey;
if (mGoogleSpreadsheets.Count>0 || string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue))
{
Spreadsheets = new List<string>(mGoogleSpreadsheets.Keys).ToArray();
SpreadsheetsKey = new List<string>(mGoogleSpreadsheets.Values).ToArray();
}
else
{
Spreadsheets = new[]{mProp_Google_SpreadsheetName.stringValue ?? string.Empty};
SpreadsheetsKey = new[]{mProp_Google_SpreadsheetKey.stringValue ?? string.Empty};
}
int mSpreadsheetIndex = Array.IndexOf(SpreadsheetsKey, mProp_Google_SpreadsheetKey.stringValue);
//--[ Spreadsheets ]------------------
GUILayout.BeginHorizontal();
GUILayout.Space(10);
GUILayout.Label ("In Google Drive:", GUILayout.Width(100));
GUI.changed = false;
GUI.enabled = Spreadsheets != null && Spreadsheets.Length>0;
mSpreadsheetIndex = EditorGUILayout.Popup(mSpreadsheetIndex, Spreadsheets, EditorStyles.toolbarPopup);
if (GUI.changed && mSpreadsheetIndex >= 0)
{
mProp_Google_SpreadsheetKey.stringValue = SpreadsheetsKey[mSpreadsheetIndex];
mProp_Google_SpreadsheetName.stringValue = Spreadsheets[mSpreadsheetIndex];
GUI.changed = false;
}
GUI.enabled = true;
GUI.enabled = !string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue) && mConnection_WWW==null;
if (GUILayout.Button("X", EditorStyles.toolbarButton,GUILayout.ExpandWidth(false)))
mProp_Google_SpreadsheetKey.stringValue = string.Empty;
GUI.enabled = true;
GUILayout.Space(10);
GUILayout.EndHorizontal();
GUILayout.Space(2);
//--[ Spreadsheets Operations ]------------------
GUILayout.BeginHorizontal();
GUILayout.Space(114);
if (GUILayout.Button("New", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
Google_NewSpreadsheet();
GUI.enabled = !string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue) && mConnection_WWW==null;
if (GUILayout.Button("Open", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
OpenGoogleSpreadsheet(mProp_Google_SpreadsheetKey.stringValue);
GUI.enabled = mConnection_WWW==null;
GUILayout.Space(5);
if (TestButton(eTest_ActionType.Button_GoogleSpreadsheet_RefreshList, "Refresh", EditorStyles.toolbarButton,GUILayout.ExpandWidth(true)))
EditorApplication.update+=Google_FindSpreadsheets;
GUILayout.Space(10);
GUILayout.EndHorizontal();
GUILayout.Space(15);
if (!string.IsNullOrEmpty(mProp_Google_SpreadsheetKey.stringValue))
OnGUI_GoogleButtons_ImportExport( mProp_Google_SpreadsheetKey.stringValue );
GUI.enabled = true;
}
private void OnGUI_ImportButtons()
{
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Import");
if (Mode != eSpreadsheetUpdateMode.None || InTestAction(eTest_ActionType.Button_GoogleSpreadsheet_Import))
{
if (mTestAction == eTest_ActionType.Button_GoogleSpreadsheet_Import)
Mode = (eSpreadsheetUpdateMode)mTestActionArg;
serializedObject.ApplyModifiedProperties();
var modeCopy = Mode;
GUITools.DelayedCall(() => Import_Google(modeCopy));
}
}
private void OnGUI_ExportButtons()
{
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Export");
if (Mode != eSpreadsheetUpdateMode.None || InTestAction(eTest_ActionType.Button_GoogleSpreadsheet_Export))
{
if (mTestAction == eTest_ActionType.Button_GoogleSpreadsheet_Export)
Mode = (eSpreadsheetUpdateMode)mTestActionArg;
serializedObject.ApplyModifiedProperties();
var modeCopy = Mode;
GUITools.DelayedCall(() => Export_Google(modeCopy));
}
}
void OnGUI_GoogleButtons_ImportExport( string SpreadsheetKey )
{
GUI.enabled = !string.IsNullOrEmpty(SpreadsheetKey) && mConnection_WWW==null;
bool vertical = EditorGUIUtility.currentViewWidth < 450;
if (vertical)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
OnGUI_ImportButtons();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
OnGUI_ExportButtons();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
else
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
OnGUI_ImportButtons();
GUILayout.FlexibleSpace();
OnGUI_ExportButtons();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
EditorGUIUtility.labelWidth += 10;
EditorGUILayout.PropertyField(mProp_Spreadsheet_SpecializationAsRows, new GUIContent("Show Specializations as Rows", "true: Make each specialization a separate row (e.g. Term[VR]..., Term[Touch]....\nfalse: Merge specializations into same cell separated by [i2s_XXX]"));
EditorGUILayout.PropertyField(mProp_Spreadsheet_SortRows, new GUIContent("Sort Rows", "true: Sort each term by its name....\nfalse: Keep the terms order"));
EditorGUIUtility.labelWidth -= 10;
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUI.enabled = true;
}
eSpreadsheetUpdateMode SynchronizationButtons( string Operation, bool ForceReplace = false )
{
eSpreadsheetUpdateMode Result = eSpreadsheetUpdateMode.None;
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Width (1));
GUI.backgroundColor = Color.white;
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(Operation, EditorStyles.miniLabel);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button( "Replace", EditorStyles.toolbarButton, GUILayout.Width(60)))
Result = eSpreadsheetUpdateMode.Replace;
if (ForceReplace) GUI.enabled = false;
if (GUILayout.Button( "Merge", EditorStyles.toolbarButton, GUILayout.Width(60)))
Result = eSpreadsheetUpdateMode.Merge;
if (GUILayout.Button( "Add New", EditorStyles.toolbarButton, GUILayout.Width(60)))
Result = eSpreadsheetUpdateMode.AddNewTerms;
GUI.enabled = mConnection_WWW==null;
GUILayout.Space(1);
GUILayout.EndHorizontal();
GUILayout.Space(2);
GUILayout.EndVertical();
if (Result != eSpreadsheetUpdateMode.None)
ClearErrors();
return Result;
}
#endregion
void VerifyGoogleService( string WebServiceURL )
{
#if UNITY_WEBPLAYER
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
#else
StopConnectionWWW();
mWebService_Status = null;
mConnection_WWW = UnityWebRequest.Get(WebServiceURL + "?action=Ping");
I2Utils.SendWebRequest(mConnection_WWW);
mConnection_Callback = OnVerifyGoogleService;
EditorApplication.update += CheckForConnection;
mConnection_Text = "Verifying Web Service";
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
#endif
}
void OnVerifyGoogleService( string Result, string Error )
{
if (Result.Contains("Authorization is required to perform that action"))
{
ShowWarning("You need to authorize the webservice before using it. Check the steps 4 and 5 in the WebService Script");
mWebService_Status = "Offline";
return;
}
try
{
var data = JSON.Parse(Result).AsObject;
int version = 0;
if (!int.TryParse(data["script_version"], out version))
version = 0;
int requiredVersion = LocalizationManager.GetRequiredWebServiceVersion();
if (requiredVersion == version)
{
mWebService_Status = "Online";
ClearErrors();
}
else
{
mWebService_Status = "UnsupportedVersion";
ShowError("The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version.");
}
}
catch (Exception)
{
ShowError("Unable to access the WebService");
mWebService_Status = "Offline";
}
}
void Export_Google( eSpreadsheetUpdateMode UpdateMode )
{
StopConnectionWWW();
LanguageSourceData source = GetSourceData();
mConnection_WWW = source.Export_Google_CreateWWWcall( UpdateMode );
if (mConnection_WWW==null)
{
OnExported_Google(string.Empty, "WebPlayer can't contact Google");
}
else
{
mConnection_Callback = OnExported_Google;
EditorApplication.update += CheckForConnection;
mConnection_Text = "Uploading spreadsheet";
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
}
}
void OnExported_Google( string Result, string Error )
{
// Checkf or error, but discard the "necessary data rewind wasn't possible" as thats not a real error, just a bug in Unity with POST redirects
if (!string.IsNullOrEmpty(Error) && !Error.Contains("rewind"))
{
Debug.Log (Error);
ShowError("Unable to access google");
return;
}
if (EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true) && !string.IsNullOrEmpty(GetSourceData().Google_SpreadsheetName))
OpenGoogleSpreadsheet(GetSourceData().Google_SpreadsheetKey );
mProp_GoogleLiveSyncIsUptoDate.boolValue = true;
}
static void OpenGoogleSpreadsheet( string SpreadsheetKey )
{
ClearErrors();
string SpreadsheetUrl = "https://docs.google.com/spreadsheet/ccc?key=" + SpreadsheetKey;
Application.OpenURL(SpreadsheetUrl);
}
public abstract LanguageSourceData GetSourceData();
void Import_Google( eSpreadsheetUpdateMode UpdateMode )
{
StopConnectionWWW();
LanguageSourceData source = GetSourceData();
mConnection_WWW = source.Import_Google_CreateWWWcall(true, false);
if (mConnection_WWW==null)
{
OnImported_Google(string.Empty, "Unable to import from google", eSpreadsheetUpdateMode.Replace);
}
else
{
mConnection_Callback=null;
switch (UpdateMode)
{
case eSpreadsheetUpdateMode.Replace : mConnection_Callback += OnImported_Google_Replace; break;
case eSpreadsheetUpdateMode.Merge : mConnection_Callback += OnImported_Google_Merge; break;
case eSpreadsheetUpdateMode.AddNewTerms : mConnection_Callback += OnImported_Google_AddNewTerms; break;
}
EditorApplication.update += CheckForConnection;
mConnection_Text = "Downloading spreadsheet";
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
}
}
void OnImported_Google_Replace( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.Replace); }
void OnImported_Google_Merge( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.Merge); }
void OnImported_Google_AddNewTerms( string Result, string Error ) { OnImported_Google(Result, Error, eSpreadsheetUpdateMode.AddNewTerms); }
void OnImported_Google( string Result, string Error, eSpreadsheetUpdateMode UpdateMode )
{
if (!string.IsNullOrEmpty(Error))
{
Debug.Log(Error);
ShowError("Unable to access google");
return;
}
LanguageSourceData source = GetSourceData();
string ErrorMsg = source.Import_Google_Result(Result, UpdateMode);
bool HasErrors = !string.IsNullOrEmpty(ErrorMsg);
if (HasErrors)
ShowError(ErrorMsg);
serializedObject.Update();
ParseTerms(true, false, !HasErrors);
mSelectedKeys.Clear ();
mSelectedCategories.Clear();
ScheduleUpdateTermsToShowInList();
mLanguageSource.GetCategories(false, mSelectedCategories);
EditorUtility.SetDirty (target);
AssetDatabase.SaveAssets();
}
void CheckForConnection()
{
if (mConnection_WWW!=null && mConnection_WWW.isDone)
{
fnConnectionCallback callback = mConnection_Callback;
string Result = string.Empty;
string Error = mConnection_WWW.error;
if (string.IsNullOrEmpty(Error))
{
// Try first converting with the right encoding
var bytes = mConnection_WWW.downloadHandler.data;
if (bytes!=null)
Result = Encoding.UTF8.GetString(bytes); //mConnection_WWW.text;
// Fallback to use the default encoding
else
Result = mConnection_WWW.downloadHandler.text;
}
StopConnectionWWW();
if (callback!=null)
callback(Result, Error);
}
/*else
if (Time.realtimeSinceStartup > mConnection_TimeOut+30)
{
fnConnectionCallback callback = mConnection_Callback;
StopConnectionWWW();
if (callback!=null)
callback(string.Empty, "Time Out");
}*/
}
void StopConnectionWWW()
{
EditorApplication.update -= CheckForConnection;
mConnection_WWW = null;
mConnection_Callback = null;
mConnection_Text = string.Empty;
}
#region New Spreadsheet
void Google_NewSpreadsheet()
{
#if UNITY_WEBPLAYER
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
#else
ClearErrors();
string SpreadsheetName;
LanguageSourceData source = GetSourceData();
if (source.IsGlobalSource())
SpreadsheetName = string.Format("{0} Localization", PlayerSettings.productName);
else
SpreadsheetName = string.Format("{0} {1} {2}", PlayerSettings.productName, Editor_GetCurrentScene(), source.ownerObject.name);
string query = mProp_Google_WebServiceURL.stringValue + "?action=NewSpreadsheet&name=" + Uri.EscapeDataString(SpreadsheetName) + "&password="+ Uri.EscapeDataString(mProp_Google_Password.stringValue);
mConnection_WWW = UnityWebRequest.Get(query);
I2Utils.SendWebRequest(mConnection_WWW);
mConnection_Callback = Google_OnNewSpreadsheet;
EditorApplication.update += CheckForConnection;
mConnection_Text = "Creating Spreadsheet";
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
#endif
}
void Google_OnNewSpreadsheet( string Result, string Error )
{
if (!string.IsNullOrEmpty(Error))
{
ShowError("Unable to access google");
return;
}
if (Result=="Wrong Password")
{
ShowError(Result);
return;
}
try
{
var data = JSON.Parse(Result).AsObject;
string name = data["name"];
string key = data["id"];
serializedObject.Update();
mProp_Google_SpreadsheetKey.stringValue = key;
mProp_Google_SpreadsheetName.stringValue = name;
serializedObject.ApplyModifiedProperties();
mGoogleSpreadsheets[name] = key;
LanguageSourceData source = GetSourceData();
if (source.mTerms.Count>0 || source.mLanguages.Count>0)
Export_Google( eSpreadsheetUpdateMode.Replace );
else
if (EditorPrefs.GetBool("I2Loc OpenDataSourceAfterExport", true))
OpenGoogleSpreadsheet( key );
}
catch(Exception e)
{
ShowError (e.Message);
}
}
#endregion
#region FindSpreadsheets
void Google_FindSpreadsheets()
{
ClearErrors();
EditorApplication.update -= Google_FindSpreadsheets;
string query = mProp_Google_WebServiceURL.stringValue + "?action=GetSpreadsheetList&password="+ Uri.EscapeDataString(mProp_Google_Password.stringValue);
mConnection_WWW = UnityWebRequest.Get(query);
I2Utils.SendWebRequest(mConnection_WWW);
mConnection_Callback = Google_OnFindSpreadsheets;
EditorApplication.update += CheckForConnection;
mConnection_Text = "Accessing google";
//mConnection_TimeOut = Time.realtimeSinceStartup + 10;
}
void Google_OnFindSpreadsheets( string Result, string Error)
{
if (!string.IsNullOrEmpty(Error))
{
ShowError("Unable to access google");
return;
}
if (Result=="Wrong Password")
{
ShowError(Result);
return;
}
try
{
mGoogleSpreadsheets.Clear();
var data = JSON.Parse(Result).AsObject;
foreach (KeyValuePair<string, JSONNode> element in data)
mGoogleSpreadsheets[element.Key] = element.Value;
}
catch(Exception e)
{
ShowError (e.Message);
}
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,339 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
enum eLocalSpreadsheeet { CSV, XLS, XLSX, NONE }
void OnGUI_Spreadsheet_Local()
{
GUILayout.Space(10);
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label ("File:", GUILayout.ExpandWidth(false));
mProp_Spreadsheet_LocalFileName.stringValue = EditorGUILayout.TextField(mProp_Spreadsheet_LocalFileName.stringValue);
/*if (GUILayout.Button("...", "toolbarbutton", GUILayout.ExpandWidth(false)))
{
string sFileName = mProp_Spreadsheet_LocalFileName.stringValue;
string sPath = string.Empty;
try {
sPath = System.IO.Path.GetDirectoryName(sFileName);
}
catch( System.Exception e){}
if (string.IsNullOrEmpty(sPath))
sPath = Application.dataPath + "/";
sFileName = System.IO.Path.GetFileName(sFileName);
if (string.IsNullOrEmpty(sFileName))
sFileName = "Localization.csv";
string FullFileName = EditorUtility.SaveFilePanel("Select CSV File", sPath, sFileName, "csv");
//string FullFileName = EditorUtility.OpenFilePanel("Select CSV, XLS or XLSX File", sFileName, "csv;*.xls;*.xlsx");
if (!string.IsNullOrEmpty(FullFileName))
{
Prop_LocalFileName.stringValue = TryMakingPathRelativeToProject(FullFileName);
}
}*/
GUILayout.EndHorizontal();
//--[ Find current extension ]---------------
eLocalSpreadsheeet CurrentExtension = eLocalSpreadsheeet.NONE;
//string FileNameLower = Prop_LocalFileName.stringValue.ToLower();
/*if (FileNameLower.EndsWith(".csv")) */CurrentExtension = eLocalSpreadsheeet.CSV;
/*if (FileNameLower.EndsWith(".xls")) CurrentExtension = eLocalSpreadsheeet.XLS;
if (FileNameLower.EndsWith(".xlsx")) CurrentExtension = eLocalSpreadsheeet.XLSX;*/
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
switch (CurrentExtension)
{
case eLocalSpreadsheeet.NONE :
case eLocalSpreadsheeet.CSV :
{
string FileTypesDesc = "Select or Drag any file of the following types:\n\n";
FileTypesDesc+= "*.csv (Comma Separated Values)\n";
FileTypesDesc+= "*.txt (CSV file renamed as txt)\n";
//FileTypesDesc+= "\n*.xls (Excel 97-2003)";
//FileTypesDesc+= "\n*.xlsx (Excel Open XML format)";
EditorGUILayout.HelpBox(FileTypesDesc, MessageType.None);
}
break;
case eLocalSpreadsheeet.XLS : EditorGUILayout.HelpBox("Excel 97-2003", MessageType.None); break;
case eLocalSpreadsheeet.XLSX : EditorGUILayout.HelpBox("Excel Open XML format", MessageType.None); break;
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
//--[ Allow Dragging files ]-----------------
if (GUILayoutUtility.GetLastRect().Contains (UnityEngine.Event.current.mousePosition) && IsValidDraggedLoadSpreadsheet())
{
if (UnityEngine.Event.current.type == EventType.DragUpdated)
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
if (UnityEngine.Event.current.type == EventType.DragPerform)
{
mProp_Spreadsheet_LocalFileName.stringValue = TryMakingPathRelativeToProject( DragAndDrop.paths[0] );
DragAndDrop.AcceptDrag();
UnityEngine.Event.current.Use();
}
}
GUILayout.Space(10);
OnGUI_Spreadsheet_Local_ImportExport( CurrentExtension, mProp_Spreadsheet_LocalFileName.stringValue );
//if (Application.platform == RuntimePlatform.OSXEditor)
//-- CSV Separator ----------------
GUI.changed = false;
var CSV_Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue;
if (string.IsNullOrEmpty (CSV_Separator))
CSV_Separator = ",";
GUILayout.Space(10);
GUILayout.BeginVertical("Box");
GUILayout.BeginHorizontal();
GUILayout.Label("Separator:");
GUILayout.FlexibleSpace();
if (GUILayout.Toggle(CSV_Separator==",", "Comma(,)") && CSV_Separator!=",")
CSV_Separator = ",";
GUILayout.FlexibleSpace();
if (GUILayout.Toggle(CSV_Separator==";", "Semicolon(;)") && CSV_Separator!=";")
CSV_Separator = ";";
GUILayout.FlexibleSpace();
if (GUILayout.Toggle(CSV_Separator=="\t", "TAB(\\t)") && CSV_Separator!="\t")
CSV_Separator = "\t";
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
//--[ Encoding ]---------------
var encodings = Encoding.GetEncodings ().OrderBy(e=>e.Name).ToArray();
var encodingNames = encodings.Select(e=>e.Name).ToArray();
int idx = Array.IndexOf (encodingNames, mProp_Spreadsheet_LocalCSVEncoding.stringValue);
if (idx == -1)
idx = Array.IndexOf (encodingNames, "utf-8");
EditorGUIUtility.labelWidth = 80;
idx = EditorGUILayout.Popup ("Encoding:", idx, encodingNames);
if (GUILayout.Button("Default", GUILayout.ExpandWidth(false)))
idx = Array.IndexOf (encodingNames, "utf-8");
if (idx>=0 && mProp_Spreadsheet_LocalCSVEncoding.stringValue != encodings [idx].Name)
mProp_Spreadsheet_LocalCSVEncoding.stringValue = encodings [idx].Name;
GUILayout.EndHorizontal();
GUILayout.EndVertical();
if (GUI.changed)
{
mProp_Spreadsheet_LocalCSVSeparator.stringValue = CSV_Separator;
}
GUILayout.Space(10);
EditorGUILayout.HelpBox("On some Mac OS, there is a Unity Bug that makes the IDE crash when selecting a CSV file in the Open/Save File Dialog.\nJust by clicking the file, unity tries to preview the content and crashes.\n\nIf any of your the team members use Mac, its adviced to import/export the CSV Files with TXT extension.", MessageType.Warning);
GUILayout.Space(10);
OnGUI_ShowMsg();
}
bool IsValidDraggedLoadSpreadsheet()
{
if (DragAndDrop.paths==null || DragAndDrop.paths.Length!=1)
return false;
string sPath = DragAndDrop.paths[0].ToLower();
if (sPath.EndsWith(".csv")) return true;
if (sPath.EndsWith(".txt")) return true;
//if (sPath.EndsWith(".xls")) return true;
//if (sPath.EndsWith(".xlsx")) return true;
/*int iChar = sPath.LastIndexOfAny( "/\\.".ToCharArray() );
if (iChar<0 || sPath[iChar]!='.')
return true;
return false;*/
return false;
}
string TryMakingPathRelativeToProject( string FileName )
{
string ProjectPath = Application.dataPath.ToLower();
string FileNameLower = FileName.ToLower();
if (FileNameLower.StartsWith(ProjectPath))
FileName = FileName.Substring(ProjectPath.Length+1);
else
if (FileNameLower.StartsWith("assets/"))
FileName = FileName.Substring("assets/".Length);
return FileName;
}
void OnGUI_Spreadsheet_Local_ImportExport( eLocalSpreadsheeet CurrentExtension, string File )
{
GUI.enabled = CurrentExtension!=eLocalSpreadsheeet.NONE;
GUILayout.BeginHorizontal();
GUILayout.Space(10);
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
eSpreadsheetUpdateMode Mode = SynchronizationButtons("Import");
if ( Mode!= eSpreadsheetUpdateMode.None)
Import_Local(File, CurrentExtension, Mode);
GUILayout.FlexibleSpace();
GUI.backgroundColor = Color.Lerp(Color.gray, Color.white, 0.5f);
Mode = SynchronizationButtons("Export", true);
if ( Mode != eSpreadsheetUpdateMode.None)
Export_Local(File, CurrentExtension, Mode);
GUILayout.Space(10);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
EditorGUIUtility.labelWidth += 10;
EditorGUILayout.PropertyField(mProp_Spreadsheet_SpecializationAsRows, new GUIContent("Show Specializations as Rows", "true: Make each specialization a separate row (e.g. Term[VR]..., Term[Touch]....\nfalse: Merge specializations into same cell separated by [i2s_XXX]"));
EditorGUILayout.PropertyField(mProp_Spreadsheet_SortRows, new GUIContent("Sort Rows", "true: Sort each term by its name....\nfalse: Keep the terms order"));
EditorGUIUtility.labelWidth -= 10;
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUI.enabled = true;
}
void Import_Local( string File, eLocalSpreadsheeet CurrentExtension, eSpreadsheetUpdateMode UpdateMode )
{
try
{
serializedObject.ApplyModifiedProperties();
serializedObject.Update();
ClearErrors();
if (string.IsNullOrEmpty(File))
File = Application.dataPath + "/Localization.csv";
else
if (!Path.IsPathRooted(File))
File = string.Concat(Application.dataPath, "/", File);
// On Mac there is an issue with previewing CSV files, so its forced to only TXT
if (Application.platform == RuntimePlatform.OSXEditor)
File = EditorUtility.OpenFilePanel("Select a CSV file renamed as TXT", File, "txt");
else
File = EditorUtility.OpenFilePanel("Select a CSV file or a CSV file renamed as TXT", File, "csv;*.txt");
//File = EditorUtility.OpenFilePanel("Select CSV, XLS or XLSX File", File, "csv;*.xls;*.xlsx");
if (!string.IsNullOrEmpty(File))
{
mLanguageSource.Spreadsheet_LocalFileName = TryMakingPathRelativeToProject(File);
switch (CurrentExtension)
{
case eLocalSpreadsheeet.CSV : Import_CSV(File, UpdateMode); break;
}
ParseTerms(true, false, true);
EditorUtility.SetDirty (target);
AssetDatabase.SaveAssets();
}
}
catch (Exception ex)
{
ShowError("Unable to import file");
Debug.LogError(ex.Message);
}
}
void Import_CSV( string FileName, eSpreadsheetUpdateMode UpdateMode )
{
LanguageSourceData source = GetSourceData();
var encoding = Encoding.GetEncoding (mProp_Spreadsheet_LocalCSVEncoding.stringValue);
if (encoding == null)
encoding = Encoding.UTF8;
string CSVstring = LocalizationReader.ReadCSVfile (FileName, encoding);
char Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue.Length>0 ? mProp_Spreadsheet_LocalCSVSeparator.stringValue[0] : ',';
string sError = source.Import_CSV( string.Empty, CSVstring, UpdateMode, Separator);
if (!string.IsNullOrEmpty(sError))
ShowError(sError);
mSelectedCategories = source.GetCategories();
}
void Export_Local( string File, eLocalSpreadsheeet CurrentExtension, eSpreadsheetUpdateMode UpdateMode )
{
try
{
serializedObject.ApplyModifiedProperties();
serializedObject.Update();
ClearErrors();
string sPath = string.Empty;
if (!Path.IsPathRooted(File))
File = string.Concat(Application.dataPath, "/", File);
try {
sPath = Path.GetDirectoryName(File);
}
catch( Exception){}
if (string.IsNullOrEmpty(sPath))
sPath = Application.dataPath + "/";
File = Path.GetFileName(File);
if (string.IsNullOrEmpty(File))
File = "Localization.csv";
if (Application.platform == RuntimePlatform.OSXEditor)
File = EditorUtility.SaveFilePanel("Select a CSV file renamed as TXT", sPath, File, "txt");
else
File = EditorUtility.SaveFilePanel("Select a CSV or TXT file", sPath, File, "csv;*.txt");
if (!string.IsNullOrEmpty(File))
{
mLanguageSource.Spreadsheet_LocalFileName = TryMakingPathRelativeToProject(File);
char Separator = mProp_Spreadsheet_LocalCSVSeparator.stringValue.Length>0 ? mProp_Spreadsheet_LocalCSVSeparator.stringValue[0] : ',';
var encoding = Encoding.GetEncoding (mProp_Spreadsheet_LocalCSVEncoding.stringValue);
if (encoding == null)
encoding = Encoding.UTF8;
switch (CurrentExtension)
{
case eLocalSpreadsheeet.CSV : Export_CSV(File, UpdateMode, Separator, encoding); break;
}
}
}
catch (Exception)
{
ShowError("Unable to export file\nCheck it is not READ-ONLY and that\nits not opened in an external viewer");
}
}
public void Export_CSV( string FileName, eSpreadsheetUpdateMode UpdateMode, char Separator, Encoding encoding )
{
LanguageSourceData source = GetSourceData();
string CSVstring = source.Export_CSV(null, Separator, mProp_Spreadsheet_SpecializationAsRows.boolValue, mProp_Spreadsheet_SortRows.boolValue);
File.WriteAllText (FileName, CSVstring, encoding);
}
}
}

View File

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

View File

@@ -0,0 +1,840 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
Vector2 mScrollPos_Keys = Vector2.zero;
public static string mKeyToExplore; // Key that should show all the language details
static string KeyList_Filter = "";
float mRowSize=-1;
float ScrollHeight;
float mTermList_MaxWidth = -1;
public static List<string> mSelectedKeys = new List<string>(); // Selected Keys in the list of mParsedKeys
public static List<string> mSelectedCategories = new List<string>();
public enum eFlagsViewKeys
{
Used = 1<<1,
Missing = 1<<2,
NotUsed = 1<<3,
Untranslated = 1<<4,
}
public static int mFlagsViewKeys = (int)eFlagsViewKeys.Used | (int)eFlagsViewKeys.NotUsed;
public static string mTermsList_NewTerm;
Rect mKeyListFilterRect;
#endregion
#region GUI Key List
float ExpandedViewHeight;
float TermsListHeight;
void OnGUI_KeysList(bool AllowExpandKey = true, float Height = 300.0f, bool ShowTools=true)
{
///if (mTermList_MaxWidth<=0)
CalculateTermsListMaxWidth();
//--[ List Filters ]--------------------------------------
// The ID of this control is registered here to avoid losing focus when the terms list grows in the scrollbox
// This control is drawn later on
int KeyListFilterID = GUIUtility.GetControlID( FocusType.Keyboard );
OnGUI_ShowMsg();
GUILayout.BeginHorizontal();
GUIStyle bstyle = new GUIStyle ("toolbarbutton");
bstyle.fontSize = 15;
if (GUILayout.Button (new GUIContent("\u21bb", "Parse Scene and update terms list with missing and unused terms"), bstyle, GUILayout.Width(25)))
EditorApplication.update += DoParseTermsInCurrentSceneAndScripts;
if (GUILayout.Button(new GUIContent("\u21ea", "Refresh the translation of all Localize objects"), bstyle, GUILayout.Width(25)))
CallLocalizeAll();
GUILayout.Space (1);
var oldFlags = mFlagsViewKeys;
mFlagsViewKeys = OnGUI_FlagToogle("Used","Shows All Terms referenced in the parsed scenes", mFlagsViewKeys, (int)eFlagsViewKeys.Used);
mFlagsViewKeys = OnGUI_FlagToogle("Not Used", "Shows all Terms from the Source that are not been used", mFlagsViewKeys, (int)eFlagsViewKeys.NotUsed);
mFlagsViewKeys = OnGUI_FlagToogle("Missing","Shows all Terms Used but not defined in the Source", mFlagsViewKeys, (int)eFlagsViewKeys.Missing);
mFlagsViewKeys = OnGUI_FlagToogle("Untranslated", "Shows all Terms that were not translated to any language", mFlagsViewKeys, (int)eFlagsViewKeys.Untranslated);
if (oldFlags!=mFlagsViewKeys)
ScheduleUpdateTermsToShowInList();
OnGUI_SelectedCategories();
GUILayout.EndHorizontal();
/*//if (UnityEngine.Event.current.type == EventType.Repaint)
TermsListHeight = Screen.height - 400;
Debug.Log(UnityEngine.Event.current.type + " " + TermsListHeight + " " + Screen.height + " " + GUILayoutUtility.GetLastRect().yMax);
//TermsListHeight = Mathf.Min(Screen.height*0.5f, TermsListHeight);
mScrollPos_Keys = GUILayout.BeginScrollView(mScrollPos_Keys, false, false, "horizontalScrollbar", "verticalScrollbar", LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(TermsListHeight));
for (int i = 0; i < 1000; ++i)
GUILayout.Label("ahhh" + i);
GUILayout.EndScrollView();
return;*/
TermsListHeight = Mathf.Min(Screen.height*0.5f, TermsListHeight);
//--[ Keys List ]-----------------------------------------
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
mScrollPos_Keys = GUILayout.BeginScrollView( mScrollPos_Keys, false, false, "horizontalScrollbar", "verticalScrollbar", LocalizeInspector.GUIStyle_OldTextArea ,GUILayout.Height(TermsListHeight)/*GUILayout.MinHeight(Height), GUILayout.MaxHeight(Screen.height), GUILayout.ExpandHeight(true)*/);
GUI.backgroundColor = Color.white;
bool bAnyValidUsage = false;
mRowSize = EditorStyles.toolbar.fixedHeight;
if (UnityEngine.Event.current!=null && UnityEngine.Event.current.type == EventType.Layout)
ScrollHeight = mScrollPos_Keys.y;
float YPosMin = -ScrollHeight;
int nSkip = 0;
int nDraw = 0;
if (mShowableTerms.Count == 0 && UnityEngine.Event.current.type == EventType.Layout)
UpdateTermsToShownInList ();
float SkipSize = 0;
foreach (var parsedTerm in mShowableTerms)
{
string sKey = parsedTerm.Term;
string sCategory = parsedTerm.Category;
string FullKey = parsedTerm.FullTerm;
int nUses = parsedTerm.Usage;
bAnyValidUsage = bAnyValidUsage | (nUses>=0);
ShowTerm_termData = parsedTerm.termData;
// Skip lines outside the view -----------------------
YPosMin += mRowSize;
SkipSize += mRowSize;
float YPosMax = YPosMin + mRowSize;
bool isExpanded = AllowExpandKey && mKeyToExplore==FullKey;
if (!isExpanded && (YPosMax<-2*mRowSize || YPosMin>/*Screen.height*/TermsListHeight+mRowSize))
{
if (YPosMin>TermsListHeight+mRowSize)
break;
nSkip++;
continue;
}
nDraw++;
//------------------------------------------------------
OnGUI_KeyHeader (sKey, sCategory, FullKey, nUses, YPosMin-mRowSize+mScrollPos_Keys.y);
//--[ Key Details ]-------------------------------
if (isExpanded)
{
GUILayout.Space(SkipSize);
SkipSize = 0;
OnGUI_KeyList_ShowKeyDetails();
Rect rect = GUILayoutUtility.GetLastRect();
if (rect.height>5)
ExpandedViewHeight = rect.height;
YPosMin += ExpandedViewHeight;
}
}
SkipSize += (mShowableTerms.Count - nDraw-nSkip) * mRowSize;
GUILayout.Space(SkipSize+2);
if (mSelectedCategories.Count < mParsedCategories.Count)
{
SkipSize += 25;
if (GUILayout.Button ("...", EditorStyles.label))
{
mSelectedCategories.Clear ();
mSelectedCategories.AddRange (mParsedCategories);
}
}
OnGUI_KeysList_AddKey();
GUILayout.Label("", GUILayout.Width(mTermList_MaxWidth+10+30), GUILayout.Height(1));
GUILayout.EndScrollView();
TermsListHeight = YPosMin + mRowSize + 25;//SkipSize+25;
//Rect ListRect = GUILayoutUtility.GetLastRect();
//if (ListRect.height>5)
// TermsListHeight = ListRect.height;
//Debug.Log(nDraw + " " + nSkip + " " + Screen.height + " " + TermsListHeight);
OnGUI_Keys_ListSelection( KeyListFilterID ); // Selection Buttons
// if (!bAnyValidUsage)
// EditorGUILayout.HelpBox("Use (Tools\\Parse Terms) to find how many times each of the Terms are used", UnityEditor.MessageType.Info);
if (ShowTools)
{
GUILayout.BeginHorizontal();
GUI.enabled = mSelectedKeys.Count>0 || !string.IsNullOrEmpty(mKeyToExplore);
if (TestButton (eTest_ActionType.Button_AddSelectedTerms, new GUIContent("Add Terms", "Add terms to Source"), "Button", GUITools.DontExpandWidth)) AddTermsToSource();
if (TestButton (eTest_ActionType.Button_RemoveSelectedTerms, new GUIContent("Remove Terms", "Remove Terms from Source"), "Button", GUITools.DontExpandWidth)) RemoveTermsFromSource();
GUILayout.FlexibleSpace ();
if (GUILayout.Button ("Change Category")) OpenTool_ChangeCategoryOfSelectedTerms();
GUI.enabled = true;
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace ();
bool newBool = GUILayout.Toggle(mLanguageSource.CaseInsensitiveTerms, "Case Insensitive Terms");
if (newBool != mLanguageSource.CaseInsensitiveTerms)
{
mProp_CaseInsensitiveTerms.boolValue = newBool;
}
GUILayout.FlexibleSpace ();
GUILayout.EndHorizontal();
}
//Debug.Log ("Draw: " + nDraw + " Skip: " + nSkip);
}
static void ScheduleUpdateTermsToShowInList()
{
if (!mUpdateShowTermIsScheduled)
{
EditorApplication.update += UpdateTermsToShownInList;
mUpdateShowTermIsScheduled = true;
}
}
static bool mUpdateShowTermIsScheduled;
static void UpdateTermsToShownInList()
{
EditorApplication.update -= UpdateTermsToShownInList;
mUpdateShowTermIsScheduled = false;
mShowableTerms.Clear ();
mSelectedCategories.Sort();
foreach (KeyValuePair<string, ParsedTerm> kvp in mParsedTerms)
{
ParsedTerm parsedTerm = kvp.Value;
if (ShouldShowTerm (parsedTerm.Term, parsedTerm.Category, parsedTerm.Usage, parsedTerm))
mShowableTerms.Add(parsedTerm);
}
GUITools.RepaintInspectors();
GUITools.ScheduleRepaintInspectors();
}
void OnGUI_KeyHeader (string sKey, string sCategory, string FullKey, int nUses, float YPosMin)
{
//--[ Toggle ]---------------------
GUI.Box(new Rect(2, YPosMin+2, 18, mRowSize), "", "Toolbar");
OnGUI_SelectableToogleListItem (new Rect(2, YPosMin+3, 15, mRowSize), FullKey, ref mSelectedKeys, "OL Toggle");
bool bEnabled = mSelectedKeys.Contains (FullKey);
//--[ Number of Objects using this key ]---------------------
if (nUses >= 0)
{
if (nUses == 0)
{
GUI.color = Color.Lerp (Color.gray, Color.white, 0.5f);
GUI.Label (new Rect(20, YPosMin+2, 30, mRowSize), nUses.ToString (), "toolbarbutton");
}
else
{
if (GUI.Button(new Rect(20, YPosMin + 2, 30, mRowSize), nUses.ToString(), "toolbarbutton"))
{
List<string> selection = new List<string>(mSelectedKeys);
if (!selection.Contains(FullKey))
selection.Add(FullKey);
List<GameObject> selGOs = new List<GameObject>();
for (int i=0; i<selection.Count; ++i)
selGOs.AddRange( FindObjectsUsingKey(selection[i]) );
if (selGOs.Count > 0)
Selection.objects = selGOs.ToArray();
else
ShowWarning("The selected Terms are not used in this Scene. Try opening other scenes");
}
}
}
else
{
GUI.color = Color.Lerp (Color.red, Color.white, 0.6f);
if (GUI.Button (new Rect(20, YPosMin+2, 30, mRowSize), "", "toolbarbutton"))
{
mCurrentToolsMode = eToolsMode.Parse;
mCurrentViewMode = eViewMode.Tools;
}
}
GUI.color = Color.white;
TermData termData = ShowTerm_termData!=null ? ShowTerm_termData : mLanguageSource.GetTermData (FullKey);
bool bKeyIsMissing = termData == null;
float MinX = 50;
if (bKeyIsMissing)
{
Rect rect = new Rect(50, YPosMin+2, mRowSize, mRowSize+2);
GUITools.DrawSkinIcon(rect, "CN EntryWarnIcon", "CN EntryWarn");
GUI.Label (rect, new GUIContent ("", "This term is used in the scene, but its not localized in the Language Source"));
MinX += rect.width;
}
else MinX += 3;
float listWidth = Mathf.Max(EditorGUIUtility.currentViewWidth / EditorGUIUtility.pixelsPerPoint, mTermList_MaxWidth);
Rect rectKey = new Rect(MinX, YPosMin+2, listWidth-MinX, mRowSize);
if (sCategory != LanguageSourceData.EmptyCategory)
rectKey.width -= 130;
if (mKeyToExplore == FullKey)
{
GUI.backgroundColor = Color.Lerp (Color.blue, Color.white, 0.8f);
if (GUI.Button (rectKey, new GUIContent (sKey, EditorStyles.foldout.onNormal.background), LocalizeInspector.GUIStyle_OldTextArea))
{
mKeyToExplore = string.Empty;
ScheduleUpdateTermsToShowInList();
ClearErrors ();
}
GUI.backgroundColor = Color.white;
}
else
{
GUIStyle LabelStyle = EditorStyles.label;
if (!bKeyIsMissing && !TermHasAllTranslations (mLanguageSource, termData))
{
LabelStyle = new GUIStyle (EditorStyles.label);
LabelStyle.fontStyle = FontStyle.Italic;
GUI.color = Color.Lerp (Color.white, Color.yellow, 0.5f);
}
if (!bEnabled)
GUI.contentColor = Color.Lerp (Color.gray, Color.white, 0.3f);
if (GUI.Button (rectKey, sKey, LabelStyle))
{
SelectTerm (FullKey);
ClearErrors ();
}
if (!bEnabled)
GUI.contentColor = Color.white;
GUI.color = Color.white;
}
//--[ Category ]--------------------------
if (sCategory != LanguageSourceData.EmptyCategory)
{
if (mKeyToExplore == FullKey)
{
rectKey.x = listWidth - 100-38-20;
rectKey.width = 130;
if (GUI.Button (rectKey, sCategory, EditorStyles.toolbarButton))
OpenTool_ChangeCategoryOfSelectedTerms ();
}
else
{
GUIStyle stl = new GUIStyle(EditorStyles.miniLabel);
stl.alignment = TextAnchor.MiddleRight;
rectKey.width = 130;//EditorStyles.miniLabel.CalcSize(new GUIContent(sCategory)).x;
rectKey.x = listWidth - rectKey.width - 38-20;
if (GUI.Button (rectKey, sCategory, stl))
{
SelectTerm (FullKey);
ClearErrors ();
}
}
}
}
void CalculateTermsListMaxWidth()
{
mTermList_MaxWidth = EditorGUIUtility.currentViewWidth / EditorGUIUtility.pixelsPerPoint - 120;
/*float maxWidth = Screen.width / 18;
foreach (KeyValuePair<string, ParsedTerm> kvp in mParsedTerms)
{
var txt = kvp.Key;
if (txt.Length > 100)
txt = txt.Substring(0, 100);
var size = EditorStyles.label.CalcSize(new GUIContent(txt));
mTermList_MaxWidth = Mathf.Max (mTermList_MaxWidth, size.x);
}*/
}
bool TermHasAllTranslations( LanguageSourceData source, TermData data )
{
if (source==null) source = LocalizationManager.Sources[0];
for (int i=0, imax=data.Languages.Length; i<imax; ++i)
{
bool isLangEnabled = source.mLanguages.Count>i ? source.mLanguages[i].IsEnabled() : true;
if (string.IsNullOrEmpty(data.Languages[i]) && isLangEnabled)
return false;
}
return true;
}
void OnGUI_KeysList_AddKey()
{
GUILayout.BeginHorizontal();
GUI.color = Color.Lerp(Color.gray, Color.white, 0.5f);
bool bWasEnabled = mTermsList_NewTerm!=null;
bool bEnabled = !GUILayout.Toggle (!bWasEnabled, "+", EditorStyles.toolbarButton, GUILayout.Width(30));
GUI.color = Color.white;
if (bWasEnabled && !bEnabled) mTermsList_NewTerm = null;
if (!bWasEnabled && bEnabled) mTermsList_NewTerm = string.Empty;
if (bEnabled)
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);
mTermsList_NewTerm = EditorGUILayout.TextField(mTermsList_NewTerm, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
LanguageSourceData.ValidateFullTerm( ref mTermsList_NewTerm );
if (string.IsNullOrEmpty(mTermsList_NewTerm) || mLanguageSource.ContainsTerm(mTermsList_NewTerm) || mTermsList_NewTerm=="-")
GUI.enabled = false;
if (TestButton (eTest_ActionType.Button_AddTerm_InTermsList, "Create Key", "toolbarbutton", GUILayout.ExpandWidth(false)))
{
AddLocalTerm(mTermsList_NewTerm);
SelectTerm( mTermsList_NewTerm );
ClearErrors();
mTermsList_NewTerm = null;
SetAllTerms_When_InferredTerms_IsInSource ();
}
GUI.enabled = true;
}
GUILayout.EndHorizontal();
}
void OpenTool_ChangeCategoryOfSelectedTerms()
{
mCurrentViewMode = eViewMode.Tools;
mCurrentToolsMode = eToolsMode.Categorize;
if (!string.IsNullOrEmpty(mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
mSelectedKeys.Add(mKeyToExplore);
mSelectedKeys.Sort();
}
void OnGUI_SelectedCategories()
{
if (mParsedCategories.Count == 0)
return;
string text = "Categories";
if (mSelectedCategories.Count() == 0)
text = "Nothing";
else
if (mSelectedCategories.Count() == mParsedCategories.Count)
text = "Everything";
else
text = mSelectedCategories.Count + " categories";
if (GUILayout.Button(new GUIContent(text), "toolbarbutton", GUILayout.Width(100)))
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("Everything"), false, () =>
{
mSelectedCategories.Clear();
mSelectedCategories.AddRange(mParsedCategories);
ScheduleUpdateTermsToShowInList();
});
menu.AddItem(new GUIContent("Nothing"), false, () =>
{
mSelectedCategories.Clear();
ScheduleUpdateTermsToShowInList();
});
menu.AddSeparator("");
var parsedList = mParsedCategories.OrderBy(x=>x).ToList();
for (int i=0, imax=parsedList.Count; i<imax ; ++i)
{
var category = parsedList[i];
var nextCategory = i + 1 < imax ? parsedList[i + 1] : null;
bool isHeader = nextCategory != null && nextCategory.StartsWith(category + "/");
var displayName = category;
var categoryRoot = category;
if (isHeader)
{
categoryRoot += "/";
var newCateg = !category.Contains('/') ? category : category.Substring(category.LastIndexOf('/') + 1);
displayName = categoryRoot + newCateg;
}
menu.AddItem(new GUIContent(displayName), !string.IsNullOrEmpty(mSelectedCategories.FirstOrDefault(x=>x.StartsWith(categoryRoot))), () =>
{
var CatHeader = category + "/";
if (mSelectedCategories.Contains(category))
{
mSelectedCategories.Remove(category);
if (isHeader)
{
mSelectedCategories.RemoveAll(x => x.StartsWith(CatHeader));
}
}
else
{
mSelectedCategories.Add(category);
if (isHeader)
{
mSelectedCategories.AddRange( parsedList.Where(x=>x.StartsWith(CatHeader)));
}
}
ScheduleUpdateTermsToShowInList();
});
if (isHeader)
{
menu.AddSeparator(category+"/");
}
}
menu.ShowAsContext();
}
}
void SaveSelectedCategories()
{
if (mSelectedCategories.Count == 0) {
EditorPrefs.DeleteKey ("I2 CategoryFilter");
} else {
var data = string.Join(",", mSelectedCategories.ToArray());
EditorPrefs.SetString ("I2 CategoryFilter", data);
}
}
void LoadSelectedCategories()
{
var data = EditorPrefs.GetString ("I2 CategoryFilter", null);
if (!string.IsNullOrEmpty(data))
{
mSelectedCategories.Clear ();
mSelectedCategories.AddRange( data.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
}
}
// Bottom part of the Key list (buttons: All, None, Used,... to select the keys)
void OnGUI_Keys_ListSelection ( int KeyListFilterID )
{
GUILayout.BeginHorizontal( "toolbarbutton" );
if (TestButton( eTest_ActionType.Button_SelectTerms_All, new GUIContent( "All", "Selects All Terms in the list" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
{
mSelectedKeys.Clear();
foreach (var kvp in mParsedTerms)
if (ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
mSelectedKeys.Add( kvp.Key );
}
if (GUILayout.Button( new GUIContent( "None", "Clears the selection" ), "toolbarbutton", GUILayout.ExpandWidth( false ) )) { mSelectedKeys.Clear(); }
GUILayout.Space( 5 );
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.Used)>1;
if (TestButton(eTest_ActionType.Button_SelectTerms_Used, new GUIContent( "Used", "Selects All Terms referenced in the parsed scenes" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
{
mSelectedKeys.Clear();
foreach (var kvp in mParsedTerms)
if (kvp.Value.Usage > 0 && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
mSelectedKeys.Add( kvp.Key );
}
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.NotUsed)>1;
if (GUILayout.Button( new GUIContent( "Not Used", "Selects all Terms from the Source that are not been used" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
{
mSelectedKeys.Clear();
foreach (var kvp in mParsedTerms)
if (kvp.Value.Usage == 0 && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
mSelectedKeys.Add( kvp.Key );
}
GUI.enabled = (mFlagsViewKeys & (int)eFlagsViewKeys.Missing)>1;
if (TestButton(eTest_ActionType.Button_SelectTerms_Missing, new GUIContent( "Missing", "Selects all Terms Used but not defined in the Source" ), "toolbarbutton", GUILayout.ExpandWidth( false ) ))
{
mSelectedKeys.Clear();
foreach (var kvp in mParsedTerms)
if (!mLanguageSource.ContainsTerm( kvp.Key ) && ShouldShowTerm( kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage ))
mSelectedKeys.Add( kvp.Key );
}
GUI.enabled = ((mFlagsViewKeys & (int)eFlagsViewKeys.Untranslated) > 1);
if (GUILayout.Button(new GUIContent("Untranslated", "Selects all Terms from the Source that are not translated to any language"), "toolbarbutton", GUILayout.ExpandWidth(false)))
{
mSelectedKeys.Clear();
foreach (var kvp in mParsedTerms)
if (kvp.Value.termData.Languages.All(o => string.IsNullOrEmpty(o)) && ShouldShowTerm(kvp.Value.Term, kvp.Value.Category, kvp.Value.Usage))
mSelectedKeys.Add(kvp.Key);
}
GUI.enabled = true;
EditorGUI.BeginChangeCheck();
// Terms Filter
{
//KeyList_Filter = EditorGUILayout.TextField(KeyList_Filter, GUI.skin.GetStyle(GUITools.Style_ToolbarSearchTextField), GUILayout.ExpandWidth(true));
GUILayout.Label( "", GUILayout.ExpandWidth( true ) );
mKeyListFilterRect = GUILayoutUtility.GetLastRect();
mKeyListFilterRect.xMax += 4;
KeyList_Filter = GUITools.TextField( mKeyListFilterRect, KeyList_Filter, 255, GUI.skin.GetStyle( GUITools.Style_ToolbarSearchTextField ), KeyListFilterID );
}
if (GUILayout.Button( string.Empty, string.IsNullOrEmpty( KeyList_Filter ) ? GUITools.Style_ToolbarSearchCancelButtonEmpty : GUITools.Style_ToolbarSearchCancelButton, GUILayout.ExpandWidth( false ) ))
{
KeyList_Filter = string.Empty;
EditorApplication.update += RepaintScene;
GUI.FocusControl( "" );
}
string filterHelp = "Fiter Options:\ntext - shows all key/categories matching text\nc text - shows all terms of the text category\nf text - show terms having 'text' in their translations";
GUILayout.Space(-5);
GUI.contentColor = new Color(1, 1, 1, 0.5f);
GUILayout.Label(new GUIContent(GUITools.Icon_Help.image, filterHelp), GUITools.DontExpandWidth);
GUI.contentColor = GUITools.White;
GUILayout.Space(-5);
if (EditorGUI.EndChangeCheck())
{
mShowableTerms.Clear();
GUI.changed = false;
}
GUILayout.EndHorizontal();
}
#endregion
#region Filtering
public bool ShouldShowTerm (string FullTerm)
{
ParsedTerm termData;
if (!mParsedTerms.TryGetValue(FullTerm, out termData))
return false;
return ShouldShowTerm (termData.Term, termData.Category, termData.Usage, termData);
}
private static TermData ShowTerm_termData;
public static bool ShouldShowTerm (string Term, string Category, int nUses, ParsedTerm parsedTerm=null )
{
if (!string.IsNullOrEmpty(Category) && !mSelectedCategories.Contains(Category))
return false;
if (Term == "-")
return false;
var fullTerm = Term;
if (!string.IsNullOrEmpty(Category) && Category != LanguageSourceData.EmptyCategory)
fullTerm = Category + "/" + Term;
if (parsedTerm != null && parsedTerm.termData != null)
ShowTerm_termData = parsedTerm.termData;
else
{
ShowTerm_termData = mLanguageSource.GetTermData (fullTerm);
if (parsedTerm!=null)
parsedTerm.termData = ShowTerm_termData;
}
var filter = KeyList_Filter.Trim();
bool useTranslation = filter.StartsWith("f ", StringComparison.OrdinalIgnoreCase);
if (useTranslation)
{
if (ShowTerm_termData == null)
return false;
filter = filter.Substring(2).Trim();
if (!string.IsNullOrEmpty(filter))
{
bool hasFilter = false;
for (int i = 0; i < ShowTerm_termData.Languages.Length; ++i)
{
if (!string.IsNullOrEmpty(ShowTerm_termData.Languages[i])
&& StringContainsFilter(ShowTerm_termData.Languages[i], filter))
{
hasFilter = true;
break;
}
}
if (!hasFilter)
return false;
}
}
else
{
bool onlyCategory = filter.StartsWith("c ", StringComparison.OrdinalIgnoreCase);
if (onlyCategory)
filter = filter.Substring(2).Trim();
if (!string.IsNullOrEmpty(filter))
{
bool matchesCategory = StringContainsFilter(Category, filter);
bool matchesName = !onlyCategory && StringContainsFilter(Term, filter);
if (!matchesCategory && !matchesName)
return false;
}
}
bool bIsMissing = ShowTerm_termData == null;
bool hasTranslation = !bIsMissing && ShowTerm_termData.Languages.Any(o => !string.IsNullOrEmpty(o));
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Untranslated) > 0) return !hasTranslation;
if (nUses<0) return true;
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Missing)>0 && bIsMissing) return true;
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Missing)==0 && bIsMissing) return false;
if ((mFlagsViewKeys & (int)eFlagsViewKeys.Used)>0 && nUses>0) return true;
if ((mFlagsViewKeys & (int)eFlagsViewKeys.NotUsed)>0 && nUses==0) return true;
return false;
}
static bool StringContainsFilter( string Term, string Filter )
{
if (string.IsNullOrEmpty(Filter) || string.IsNullOrEmpty(Term))
return true;
if (Term == "-")
return false;
Term = Term.ToLower();
string[] Filters = Filter.ToLower().Split(";, ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
for (int i = 0, imax = Filters.Length; i < imax; ++i)
if (Term.Contains(Filters[i]))
return true;
return false;
}
#endregion
#region Add/Remove Keys to DB
void AddTermsToSource()
{
if (!string.IsNullOrEmpty (mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
mSelectedKeys.Add (mKeyToExplore);
for (int i=mSelectedKeys.Count-1; i>=0; --i)
{
string key = mSelectedKeys[i];
if (!ShouldShowTerm(key))
continue;
AddLocalTerm(key);
mSelectedKeys.RemoveAt(i);
}
SetAllTerms_When_InferredTerms_IsInSource ();
}
void RemoveTermsFromSource()
{
if (mTestAction==eTest_ActionType.None && !EditorUtility.DisplayDialog("Confirm delete", "Are you sure you want to delete the selected terms", "Yes", "Cancel"))
return;
if (!string.IsNullOrEmpty (mKeyToExplore) && !mSelectedKeys.Contains(mKeyToExplore))
mSelectedKeys.Add (mKeyToExplore);
for (int i=mSelectedKeys.Count-1; i>=0; --i)
{
string key = mSelectedKeys[i];
if (!ShouldShowTerm(key))
continue;
mLanguageSource.RemoveTerm(key);
RemoveParsedTerm(key);
mSelectedKeys.Remove(key);
}
mKeyToExplore = string.Empty;
mTermList_MaxWidth = -1;
serializedObject.ApplyModifiedProperties();
mLanguageSource.Editor_SetDirty();
EditorApplication.update += DoParseTermsInCurrentScene;
EditorApplication.update += RepaintScene;
}
#endregion
#region Select Objects in Current Scene
public static void SelectTerm( string Key, bool SwitchToKeysTab=false )
{
GUI.FocusControl(null);
mKeyToExplore = Key;
mKeysDesc_AllowEdit = false;
if (SwitchToKeysTab)
mCurrentViewMode = eViewMode.Keys;
}
void SelectObjectsUsingKey( string Key )
{
List<GameObject> SelectedObjs = FindObjectsUsingKey(Key);
if (SelectedObjs.Count>0)
Selection.objects = SelectedObjs.ToArray();
else
ShowWarning("The selected Terms are not used in this Scene. Try opening other scenes");
}
List<GameObject> FindObjectsUsingKey(string Key)
{
List<GameObject> SelectedObjs = new List<GameObject>();
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize));
if (Locals == null)
return SelectedObjs;
for (int i = 0, imax = Locals.Length; i < imax; ++i)
{
Localize localize = Locals[i];
if (localize == null || localize.gameObject == null || !GUITools.ObjectExistInScene(localize.gameObject))
continue;
string Term, SecondaryTerm;
localize.GetFinalTerms(out Term, out SecondaryTerm);
if (Key == Term || Key == SecondaryTerm)
SelectedObjs.Add(localize.gameObject);
}
return SelectedObjs;
}
#endregion
[MenuItem("Tools/I2 Localization/Refresh Localizations", false, 16)]
public static void CallLocalizeAll()
{
LocalizationManager.LocalizeAll(true);
HandleUtility.Repaint();
}
}
}

View File

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

View File

@@ -0,0 +1,785 @@
//#define UGUI
//#define NGUI
using System;
using TMPro;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
internal static bool mKeysDesc_AllowEdit;
internal static string GUI_SelectedSpecialization
{
get{
if (string.IsNullOrEmpty(mGUI_SelectedSpecialization))
mGUI_SelectedSpecialization = EditorPrefs.GetString ("I2Loc Specialization", "Any");
return mGUI_SelectedSpecialization;
}
set{
if (value!=mGUI_SelectedSpecialization)
EditorPrefs.SetString ("I2Loc Specialization", value);
mGUI_SelectedSpecialization = value;
}
}
internal static string mGUI_SelectedSpecialization;
internal static bool GUI_ShowDisabledLanguagesTranslation = true;
internal static int mShowPlural = -1;
#endregion
#region Key Description
void OnGUI_KeyList_ShowKeyDetails()
{
GUI.backgroundColor = Color.Lerp(Color.blue, Color.white, 0.9f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
OnGUI_Keys_Languages(mKeyToExplore, null);
GUILayout.BeginHorizontal();
if (TestButton(eTest_ActionType.Button_DeleteTerm, "Delete", "Button", GUILayout.ExpandWidth(true)))
{
if (mTestAction != eTest_ActionType.None || EditorUtility.DisplayDialog("Confirm delete", "Are you sure you want to delete term '" + mKeyToExplore + "'", "Yes", "Cancel"))
EditorApplication.update += DeleteCurrentKey;
}
if (GUILayout.Button("Rename"))
{
mCurrentViewMode = eViewMode.Tools;
mCurrentToolsMode = eToolsMode.Merge;
if (!mSelectedKeys.Contains(mKeyToExplore))
mSelectedKeys.Add(mKeyToExplore);
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUI.backgroundColor = Color.white;
}
void DeleteTerm( string Term, bool updateStructures = true )
{
mLanguageSource.RemoveTerm (Term);
RemoveParsedTerm(Term);
mSelectedKeys.Remove(Term);
if (Term==mKeyToExplore)
mKeyToExplore = string.Empty;
if (updateStructures)
{
UpdateParsedCategories();
mTermList_MaxWidth = -1;
serializedObject.ApplyModifiedProperties();
mLanguageSource.Editor_SetDirty();
ScheduleUpdateTermsToShowInList();
}
EditorApplication.update += RepaintScene;
}
void RepaintScene()
{
EditorApplication.update -= RepaintScene;
Repaint();
}
void DeleteCurrentKey()
{
EditorApplication.update -= DeleteCurrentKey;
DeleteTerm (mKeyToExplore);
mKeyToExplore = "";
EditorApplication.update += DoParseTermsInCurrentScene;
}
TermData AddLocalTerm( string Term, bool AutoSelect = true )
{
var data = AddTerm(Term, AutoSelect);
if (data==null)
return null;
mTermList_MaxWidth = -1;
serializedObject.ApplyModifiedProperties();
mLanguageSource.Editor_SetDirty();
return data;
}
static TermData AddTerm(string Term, bool AutoSelect = true, eTermType termType = eTermType.Text)
{
if (Term == "-" || string.IsNullOrEmpty(Term))
return null;
Term = I2Utils.GetValidTermName(Term, true);
TermData data = mLanguageSource.AddTerm(Term, termType);
GetParsedTerm(Term);
string sCategory = LanguageSourceData.GetCategoryFromFullTerm(Term);
mParsedCategories.Add(sCategory);
if (AutoSelect)
{
if (!mSelectedKeys.Contains(Term))
mSelectedKeys.Add(Term);
if (!mSelectedCategories.Contains(sCategory))
mSelectedCategories.Add(sCategory);
}
ScheduleUpdateTermsToShowInList();
mLanguageSource.Editor_SetDirty();
return data;
}
// this method shows the key description and the localization to each language
public static TermData OnGUI_Keys_Languages( string Key, Localize localizeCmp, bool IsPrimaryKey=true )
{
if (Key==null)
Key = string.Empty;
TermData termdata = null;
LanguageSourceData source = mLanguageSource;
if (localizeCmp != null && localizeCmp.Source != null)
source = localizeCmp.Source.SourceData;
if (source==null)
source = LocalizationManager.GetSourceContaining(Key, false);
if (source==null)
{
if (localizeCmp == null)
source = LocalizationManager.Sources[0];
else
source = LocalizationManager.GetSourceContaining(IsPrimaryKey ? localizeCmp.SecondaryTerm : localizeCmp.Term);
}
if (string.IsNullOrEmpty(Key))
{
EditorGUILayout.HelpBox( "Select a Term to Localize", MessageType.Info );
return null;
}
termdata = source.GetTermData(Key);
if (termdata==null && localizeCmp!=null)
{
var realSource = LocalizationManager.GetSourceContaining(Key, false);
if (realSource != null)
{
termdata = realSource.GetTermData(Key);
source = realSource;
}
}
if (termdata==null)
{
if (Key == "-")
return null;
EditorGUILayout.HelpBox( string.Format("Key '{0}' is not Localized or it is in a different Language Source", Key), MessageType.Error );
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Add Term to Source"))
{
var termType = eTermType.Text;
if (localizeCmp!=null && localizeCmp.mLocalizeTarget != null)
{
termType = IsPrimaryKey ? localizeCmp.mLocalizeTarget.GetPrimaryTermType(localizeCmp)
: localizeCmp.mLocalizeTarget.GetSecondaryTermType(localizeCmp);
}
AddTerm(Key, true, termType);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
return null;
}
//--[ Type ]----------------------------------
if (localizeCmp==null)
{
GUILayout.BeginHorizontal();
GUILayout.Label ("Type:", GUILayout.ExpandWidth(false));
eTermType NewType = (eTermType)EditorGUILayout.EnumPopup(termdata.TermType, GUILayout.ExpandWidth(true));
if (termdata.TermType != NewType)
termdata.TermType = NewType;
GUILayout.EndHorizontal();
}
//--[ Description ]---------------------------
mKeysDesc_AllowEdit = GUILayout.Toggle(mKeysDesc_AllowEdit, "Description", EditorStyles.foldout, GUILayout.ExpandWidth(true));
if (mKeysDesc_AllowEdit)
{
string NewDesc = EditorGUILayout.TextArea( termdata.Description, Style_WrapTextField );
if (NewDesc != termdata.Description)
{
termdata.Description = NewDesc;
source.Editor_SetDirty();
}
}
else
EditorGUILayout.HelpBox( string.IsNullOrEmpty(termdata.Description) ? "No description" : termdata.Description, MessageType.Info );
OnGUI_Keys_Language_SpecializationsBar (termdata, source);
OnGUI_Keys_Languages(Key, ref termdata, localizeCmp, IsPrimaryKey, source);
return termdata;
}
static void OnGUI_Keys_Languages( string Key, ref TermData termdata, Localize localizeCmp, bool IsPrimaryKey, LanguageSourceData source )
{
//--[ Languages ]---------------------------
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
OnGUI_Keys_LanguageTranslations(Key, localizeCmp, IsPrimaryKey, ref termdata, source);
if (termdata.TermType == eTermType.Text)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (TestButton(eTest_ActionType.Button_Term_TranslateAll, "Translate All", "Button", GUILayout.Width(85)))
{
var termData = termdata;
GUITools.DelayedCall(() => TranslateLanguage( Key, termData, localizeCmp, source));
GUI.FocusControl(string.Empty);
}
GUILayout.EndHorizontal();
OnGUI_TranslatingMessage();
}
GUILayout.EndVertical();
}
static void TranslateLanguage( string Key, TermData termdata, Localize localizeCmp, LanguageSourceData source)
{
ClearErrors();
string mainText = localizeCmp == null ? LanguageSourceData.GetKeyFromFullTerm(Key) : localizeCmp.GetMainTargetsText();
for (int i = 0; i < source.mLanguages.Count; ++i)
if (source.mLanguages[i].IsEnabled() && string.IsNullOrEmpty(termdata.Languages[i]))
{
var langIdx = i;
var term = termdata;
var i2source = source;
Translate(mainText, ref termdata, source.mLanguages[i].Code,
(translation, error) =>
{
if (error != null)
ShowError(error);
else
if (translation != null)
{
term.Languages[langIdx] = translation; //SetTranslation(langIdx, translation);
i2source.Editor_SetDirty();
}
}, null);
}
}
static void OnGUI_TranslatingMessage()
{
if (GoogleTranslation.IsTranslating())
{
// Connection Status Bar
int time = (int)(Time.realtimeSinceStartup % 2 * 2.5);
string Loading = "Translating" + ".....".Substring(0, time);
GUI.color = Color.gray;
GUILayout.BeginHorizontal(LocalizeInspector.GUIStyle_OldTextArea);
GUILayout.Label(Loading, EditorStyles.miniLabel);
GUI.color = Color.white;
if (GUILayout.Button("Cancel", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
GoogleTranslation.CancelCurrentGoogleTranslations();
}
GUILayout.EndHorizontal();
HandleUtility.Repaint ();
}
}
static void OnGUI_Keys_Language_SpecializationsBar(TermData termData, LanguageSourceData source)
{
var activeSpecializations = termData.GetAllSpecializations();
GUILayout.BeginHorizontal();
var TabStyle = new GUIStyle(GUI.skin.FindStyle("dragtab"));
TabStyle.fixedHeight = 0;
//var ss = GUI.skin.FindStyle("TL tab left");
var TabOpenStyle = new GUIStyle(GUI.skin.FindStyle("minibuttonmid"));
TabOpenStyle.margin.right = -1;
var TabCloseStyle = new GUIStyle(EditorStyles.label);
//var TabCloseStyle = new GUIStyle(GUI.skin.FindStyle("TL tab right"));
TabCloseStyle.margin.left = -1;
TabCloseStyle.padding.left=4;
//-- Specialization Tabs -----
var prevSpecialization = "Any";
foreach (var specialization in SpecializationManager.Singleton.mSpecializations)
{
if (!activeSpecializations.Contains(specialization) && specialization != GUI_SelectedSpecialization)
continue;
bool isActive = specialization == GUI_SelectedSpecialization;
var labelContent = new GUIContent(specialization, "Specialization of the main translation (i.e. variants that show only on specific platforms or devices)\nThis allows using 'tap' instead of 'click' for touch devices.");
if (isActive && activeSpecializations.Count>1)
{
GUILayout.BeginHorizontal(TabOpenStyle);
GUILayout.Toggle(isActive, labelContent, TabStyle, GUILayout.Height(20), GUILayout.ExpandWidth(false));
//GUILayout.Label(labelContent, TabOpenStyle);
if (specialization != "Any" && GUILayout.Button("x", TabCloseStyle, GUILayout.Width(15)))
{
termData.RemoveSpecialization(specialization);
GUI_SelectedSpecialization = prevSpecialization;
GUI.FocusControl(null);
}
GUILayout.EndHorizontal();
}
else
if (GUILayout.Toggle(isActive, labelContent, TabStyle, GUILayout.Height(25), GUILayout.ExpandWidth(false)) && !isActive)
{
GUI_SelectedSpecialization = specialization;
GUI.FocusControl(null);
}
}
//-- Add new Specialization -----
int newIndex = EditorGUILayout.Popup(-1, SpecializationManager.Singleton.mSpecializations, "DropDown", GUILayout.Width(20));
if (newIndex>=0)
{
string newSpecialization = SpecializationManager.Singleton.mSpecializations[newIndex];
if (!activeSpecializations.Contains(newSpecialization))
{
for (int iLang = 0; iLang < source.mLanguages.Count; ++iLang)
{
string Translation = termData.GetTranslation(iLang, GUI_SelectedSpecialization, editMode: true);
termData.SetTranslation(iLang, Translation, GUI_SelectedSpecialization);
}
GUI_SelectedSpecialization = newSpecialization;
}
}
GUILayout.FlexibleSpace();
GUI_ShowDisabledLanguagesTranslation = GUILayout.Toggle(GUI_ShowDisabledLanguagesTranslation, new GUIContent("L", "Show Disabled Languages"), "Button", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
GUILayout.Space(-3);
}
static void OnGUI_Keys_LanguageTranslations (string Key, Localize localizeCmp, bool IsPrimaryKey, ref TermData termdata, LanguageSourceData source)
{
bool IsSelect = UnityEngine.Event.current.type==EventType.MouseUp;
for (int i=0; i< source.mLanguages.Count; ++ i)
{
bool forcePreview = false;
bool isEnabledLanguage = source.mLanguages[i].IsEnabled();
if (!isEnabledLanguage)
{
if (!GUI_ShowDisabledLanguagesTranslation)
continue;
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.35f);
}
GUILayout.BeginHorizontal();
if (GUILayout.Button(source.mLanguages[i].Name, EditorStyles.label, GUILayout.Width(100)))
forcePreview = true;
string Translation = termdata.GetTranslation(i, GUI_SelectedSpecialization, editMode:true);
if (Translation == null) Translation = string.Empty;
// if (termdata.Languages[i] != termdata.Languages_Touch[i] && !string.IsNullOrEmpty(termdata.Languages[i]) && !string.IsNullOrEmpty(termdata.Languages_Touch[i]))
// GUI.contentColor = GUITools.LightYellow;
if (termdata.TermType == eTermType.Text || termdata.TermType==eTermType.Child)
{
EditorGUI.BeginChangeCheck ();
string CtrName = "TranslatedText"+i;
GUI.SetNextControlName(CtrName);
EditPluralTranslations (ref Translation, i, source.mLanguages[i].Code);
//Translation = EditorGUILayout.TextArea(Translation, Style_WrapTextField, GUILayout.Width(Screen.width - 260 - (autoTranslated ? 20 : 0)));
if (EditorGUI.EndChangeCheck ())
{
termdata.SetTranslation(i, Translation, GUI_SelectedSpecialization);
source.Editor_SetDirty();
forcePreview = true;
}
if (localizeCmp!=null &&
(forcePreview || /*GUI.changed || */GUI.GetNameOfFocusedControl()==CtrName && IsSelect))
{
if (IsPrimaryKey && string.IsNullOrEmpty(localizeCmp.Term))
{
localizeCmp.mTerm = Key;
}
if (!IsPrimaryKey && string.IsNullOrEmpty(localizeCmp.SecondaryTerm))
{
localizeCmp.mTermSecondary = Key;
}
string PreviousLanguage = LocalizationManager.CurrentLanguage;
LocalizationManager.PreviewLanguage(source.mLanguages[i].Name);
if (forcePreview || IsSelect)
LocalizationManager.LocalizeAll();
else
localizeCmp.OnLocalize(true);
LocalizationManager.PreviewLanguage(PreviousLanguage);
EditorUtility.SetDirty(localizeCmp);
}
GUI.contentColor = Color.white;
//if (autoTranslated)
//{
// if (GUILayout.Button(new GUIContent("\u2713"/*"A"*/,"Translated by Google Translator\nClick the button to approve the translation"), EditorStyles.toolbarButton, GUILayout.Width(autoTranslated ? 20 : 0)))
// {
// termdata.Flags[i] &= (byte)(byte.MaxValue ^ (byte)(GUI_SelectedSpecialization==0 ? TranslationFlag.AutoTranslated_Normal : TranslationFlag.AutoTranslated_Touch));
// }
//}
if (termdata.TermType == eTermType.Text)
{
if (TestButtonArg(eTest_ActionType.Button_Term_Translate, i, new GUIContent("T", "Translate"), EditorStyles.toolbarButton, GUILayout.Width(20)))
{
var termData = termdata;
var indx = i;
var key = Key;
GUITools.DelayedCall(()=>TranslateTerm(key, termData, source, indx));
GUI.FocusControl(string.Empty);
}
}
}
else
{
string MultiSpriteName = string.Empty;
if (termdata.TermType==eTermType.Sprite && Translation.EndsWith("]", StringComparison.Ordinal)) // Handle sprites of type (Multiple): "SpritePath[SpriteName]"
{
int idx = Translation.LastIndexOf("[", StringComparison.Ordinal);
int len = Translation.Length-idx-2;
MultiSpriteName = Translation.Substring(idx+1, len);
Translation = Translation.Substring(0, idx);
}
Object Obj = null;
// Try getting the asset from the References section
if (localizeCmp!=null)
Obj = localizeCmp.FindTranslatedObject<Object>(Translation);
if (Obj==null && source != null)
Obj = source.FindAsset(Translation);
// If it wasn't in the references, Load it from Resources
if (Obj==null && localizeCmp==null)
Obj = ResourceManager.pInstance.LoadFromResources<Object>(Translation);
Type ObjType = typeof(Object);
switch (termdata.TermType)
{
case eTermType.Font : ObjType = typeof(Font); break;
case eTermType.Texture : ObjType = typeof(Texture); break;
case eTermType.AudioClip : ObjType = typeof(AudioClip); break;
case eTermType.GameObject : ObjType = typeof(GameObject); break;
case eTermType.Sprite : ObjType = typeof(Sprite); break;
case eTermType.Material : ObjType = typeof(Material); break;
case eTermType.Mesh : ObjType = typeof(Mesh); break;
#if NGUI
case eTermType.UIAtlas : ObjType = typeof(UIAtlas); break;
case eTermType.UIFont : ObjType = typeof(UIFont); break;
#endif
#if TK2D
case eTermType.TK2dFont : ObjType = typeof(tk2dFont); break;
case eTermType.TK2dCollection : ObjType = typeof(tk2dSpriteCollection); break;
#endif
#if TextMeshPro
case eTermType.TextMeshPFont : ObjType = typeof(TMP_FontAsset); break;
#endif
#if SVG
case eTermType.SVGAsset : ObjType = typeof(SVGImporter.SVGAsset); break;
#endif
case eTermType.Object : ObjType = typeof(Object); break;
}
if (Obj!=null && !string.IsNullOrEmpty(MultiSpriteName))
{
string sPath = AssetDatabase.GetAssetPath(Obj);
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(sPath);
Obj = null;
for (int j=0, jmax=objs.Length; j<jmax; ++j)
if (objs[j].name.Equals(MultiSpriteName))
{
Obj = objs[j];
break;
}
}
bool bShowTranslationLabel = Obj==null && !string.IsNullOrEmpty(Translation);
if (bShowTranslationLabel)
{
GUI.backgroundColor=GUITools.DarkGray;
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
GUILayout.Space(2);
GUI.backgroundColor = Color.white;
}
Object NewObj = EditorGUILayout.ObjectField(Obj, ObjType, true, GUILayout.ExpandWidth(true));
if (Obj!=NewObj)
{
string sPath = null;
if (NewObj != null)
{
sPath = AssetDatabase.GetAssetPath(NewObj);
mCurrentInspector.serializedObject.ApplyModifiedProperties();
foreach (var cmp in mCurrentInspector.serializedObject.targetObjects)
{
AddObjectPath(ref sPath, cmp as Localize, NewObj);
}
mCurrentInspector.serializedObject.ApplyModifiedProperties();
if (HasObjectInReferences(NewObj, localizeCmp))
sPath = NewObj.name;
else
if (termdata.TermType == eTermType.Sprite)
sPath += "[" + NewObj.name + "]";
}
termdata.SetTranslation(i, sPath, GUI_SelectedSpecialization);
source.Editor_SetDirty();
}
if (bShowTranslationLabel)
{
GUILayout.BeginHorizontal();
GUI.color = Color.red;
GUILayout.FlexibleSpace();
GUILayout.Label (Translation, EditorStyles.miniLabel);
GUILayout.FlexibleSpace();
GUI.color = Color.white;
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
}
GUILayout.EndHorizontal();
GUI.color = Color.white;
}
}
private static void TranslateTerm(string Key, TermData termdata, LanguageSourceData source, int i)
{
string sourceText = null;
string sourceLangCode = null;
FindTranslationSource(Key, termdata, source.mLanguages[i].Code, null, out sourceText, out sourceLangCode);
var term = termdata;
var specialization = GUI_SelectedSpecialization;
var langIdx = i;
var i2source = source;
Translate(sourceText, ref termdata, source.mLanguages[i].Code, (translation, error) =>
{
term.SetTranslation(langIdx, translation, specialization);
i2source.Editor_SetDirty();
}, specialization);
}
static void EditPluralTranslations( ref string translation, int langIdx, string langCode )
{
bool hasParameters = false;
int paramStart = translation.IndexOf("{[");
hasParameters = paramStart >= 0 && translation.IndexOf ("]}", paramStart) > 0;
if (mShowPlural == langIdx && string.IsNullOrEmpty (translation))
mShowPlural = -1;
bool allowPlural = hasParameters || translation.Contains("[i2p_");
if (allowPlural)
{
if (GUILayout.Toggle (mShowPlural == langIdx, "", EditorStyles.foldout, GUILayout.Width (13)))
mShowPlural = langIdx;
else if (mShowPlural == langIdx)
mShowPlural = -1;
GUILayout.Space (-5);
}
string finalTranslation = "";
bool unfolded = mShowPlural == langIdx;
bool isPlural = allowPlural && translation.Contains("[i2p_");
if (unfolded)
GUILayout.BeginVertical ("Box");
ShowPluralTranslation("Plural", langCode, translation, ref finalTranslation, true, unfolded, unfolded|isPlural );
ShowPluralTranslation("Zero", langCode, translation, ref finalTranslation, unfolded, true, true );
ShowPluralTranslation("One", langCode, translation, ref finalTranslation, unfolded, true, true );
ShowPluralTranslation("Two", langCode, translation, ref finalTranslation, unfolded, true, true );
ShowPluralTranslation("Few", langCode, translation, ref finalTranslation, unfolded, true, true );
ShowPluralTranslation("Many", langCode, translation, ref finalTranslation, unfolded, true, true );
if (unfolded)
GUILayout.EndVertical ();
translation = finalTranslation;
}
static void ShowPluralTranslation(string pluralType, string langCode, string translation, ref string finalTranslation, bool show, bool allowDelete, bool showTag )
{
string tag = "[i2p_" + pluralType + "]";
int idx0 = translation.IndexOf (tag, StringComparison.OrdinalIgnoreCase);
bool hasTranslation = idx0 >= 0 || pluralType=="Plural";
if (idx0 < 0) idx0 = 0;
else idx0 += tag.Length;
int idx1 = translation.IndexOf ("[i2p_", idx0, StringComparison.OrdinalIgnoreCase);
if (idx1 < 0) idx1 = translation.Length;
var pluralTranslation = translation.Substring(idx0, idx1-idx0);
var newTrans = pluralTranslation;
bool allowPluralForm = GoogleLanguages.LanguageHasPluralType (langCode, pluralType);
if (hasTranslation && !allowPluralForm) {
newTrans = "";
GUI.changed = true;
}
if (show && allowPluralForm)
{
if (!hasTranslation)
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.35f);
GUILayout.BeginHorizontal ();
if (showTag)
GUILayout.Label (pluralType, EditorStyles.miniLabel, GUILayout.Width(35));
newTrans = EditorGUILayout.TextArea (pluralTranslation, Style_WrapTextField);
if (allowDelete && GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.Width(15)))
{
newTrans = string.Empty;
GUI.changed = true;
GUIUtility.keyboardControl = 0;
}
GUILayout.EndHorizontal ();
if (!hasTranslation)
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 1);
}
if (!string.IsNullOrEmpty (newTrans))
{
if (hasTranslation || newTrans != pluralTranslation)
{
if (pluralType != "Plural")
finalTranslation += tag;
finalTranslation += newTrans;
}
}
}
/*static public int DrawTranslationTabs( int Index )
{
GUIStyle MyStyle = new GUIStyle(GUI.skin.FindStyle("dragtab"));
MyStyle.fixedHeight=0;
GUILayout.BeginHorizontal();
for (int i=0; i<Tabs.Length; ++i)
{
if ( GUILayout.Toggle(Index==i, Tabs[i], MyStyle, GUILayout.Height(height)) && Index!=i)
Index=i;
}
GUILayout.EndHorizontal();
return Index;
}*/
static bool HasObjectInReferences( Object obj, Localize localizeCmp )
{
if (localizeCmp!=null && localizeCmp.TranslatedObjects.Contains(obj))
return true;
if (mLanguageSource!=null && mLanguageSource.Assets.Contains(obj))
return true;
return false;
}
static void AddObjectPath( ref string sPath, Localize localizeCmp, Object NewObj )
{
if (I2Utils.RemoveResourcesPath (ref sPath))
return;
// If its not in the Resources folder and there is no object reference already in the
// Reference array, then add that to the Localization component or the Language Source
if (HasObjectInReferences(NewObj, localizeCmp))
return;
if (localizeCmp!=null)
{
localizeCmp.AddTranslatedObject(NewObj);
EditorUtility.SetDirty(localizeCmp);
}
else
if (mLanguageSource!=null)
{
mLanguageSource.AddAsset(NewObj);
mLanguageSource.Editor_SetDirty();
}
}
static void Translate ( string Key, ref TermData termdata, string TargetLanguageCode, GoogleTranslation.fnOnTranslated onTranslated, string overrideSpecialization )
{
#if UNITY_WEBPLAYER
ShowError ("Contacting google translation is not yet supported on WebPlayer" );
#else
if (!GoogleTranslation.CanTranslate())
{
ShowError ("WebService is not set correctly or needs to be reinstalled");
return;
}
// Translate first language that has something
// If no language found, translation will fallback to autodetect language from key
string sourceCode, sourceText;
FindTranslationSource( Key, termdata, TargetLanguageCode, overrideSpecialization, out sourceText, out sourceCode );
GoogleTranslation.Translate( sourceText, sourceCode, TargetLanguageCode, onTranslated );
#endif
}
static void FindTranslationSource( string Key, TermData termdata, string TargetLanguageCode, string forceSpecialization, out string sourceText, out string sourceLanguageCode )
{
sourceLanguageCode = "auto";
sourceText = Key;
for (int i = 0, imax = termdata.Languages.Length; i < imax; ++i)
{
if (mLanguageSource.mLanguages[i].IsEnabled() && !string.IsNullOrEmpty(termdata.Languages[i]))
{
sourceText = forceSpecialization==null ? termdata.Languages[i] : termdata.GetTranslation(i, forceSpecialization, editMode:true);
if (mLanguageSource.mLanguages[i].Code != TargetLanguageCode)
{
sourceLanguageCode = mLanguageSource.mLanguages[i].Code;
return;
}
}
}
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,49 @@
using System.Collections.Generic;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
Vector2 mScrollPos_BuildScenes = Vector2.zero;
static List<string> mSelectedScenes = new List<string>();
public enum eToolsMode { Parse, Categorize, Merge, NoLocalized, Script, CharSet }
public eToolsMode mCurrentToolsMode = eToolsMode.Parse;
#endregion
#region GUI
void OnGUI_Tools( bool reset )
{
GUILayout.Space(10);
eToolsMode OldMode = mCurrentToolsMode;
mCurrentToolsMode = (eToolsMode)GUITools.DrawShadowedTabs ((int)mCurrentToolsMode, new[]{"Parse", "Categorize", "Merge", "No Localized", "Script", "CharSet"}, 30);
if (mCurrentToolsMode != OldMode || reset)
{
ClearErrors();
if (mCurrentToolsMode == eToolsMode.Script)
SelectTermsFromScriptLocalization();
OnGUI_ScenesList_SelectAllScenes(true);
}
switch (mCurrentToolsMode)
{
case eToolsMode.Parse : OnGUI_Tools_ParseTerms(); break;
case eToolsMode.Categorize : OnGUI_Tools_Categorize(); break;
case eToolsMode.Merge : OnGUI_Tools_MergeTerms(); break;
case eToolsMode.NoLocalized : OnGUI_Tools_NoLocalized(); break;
case eToolsMode.Script : OnGUI_Tools_Script(); break;
case eToolsMode.CharSet : OnGUI_Tools_CharSet(); break;
}
OnGUI_ShowMsg();
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
Vector2 mScrollPos_CategorizedKeys = Vector2.zero;
string mNewCategory = string.Empty;
#endregion
#region GUI
void OnGUI_Tools_Categorize()
{
OnGUI_ScenesList(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 (5);
EditorGUILayout.HelpBox("This tool changes the category of the selected Terms and updates the highlighted scenes", MessageType.Info);
GUILayout.Space (5);
GUITools.CloseHeader();
OnGUI_Tools_Categorize_Terms();
OnGUI_NewOrExistingCategory();
}
void OnGUI_Tools_Categorize_Terms()
{
GUILayout.Label("Change Category of the following Terms:", EditorStyles.toolbarButton, GUILayout.ExpandWidth(true));
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
mScrollPos_CategorizedKeys = GUILayout.BeginScrollView( mScrollPos_CategorizedKeys, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height ( 100));
GUI.backgroundColor = Color.white;
if (mSelectedKeys.Count==0)
{
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
//GUILayout.BeginVertical();
EditorGUILayout.HelpBox("No Terms has been selected", MessageType.Warning);
/*if (GUILayout.Button("Select Terms", EditorStyles.toolbarButton, GUILayout.ExpandWidth(true)))
mCurrentViewMode = eViewMode.Keys;*/
//GUILayout.EndVertical();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
}
else
{
bool DoubleColumn = mSelectedKeys.Count>5;
int HalfCount = Mathf.CeilToInt(mSelectedKeys.Count/2.0f);
for (int i=0, imax=mSelectedKeys.Count; i<imax; ++i)
{
if (DoubleColumn && i>=HalfCount) break;
GUILayout.BeginHorizontal();
OnGUI_CategorizedTerm(mSelectedKeys[i]);
if (DoubleColumn && i+HalfCount<mSelectedKeys.Count)
OnGUI_CategorizedTerm(mSelectedKeys[i+HalfCount]);
GUILayout.EndHorizontal();
}
}
GUILayout.EndScrollView();
}
void OnGUI_CategorizedTerm( string Term )
{
GUILayout.BeginHorizontal();
string sKey, sCategory;
LanguageSourceData.DeserializeFullTerm(Term, out sKey, out sCategory);
if (!string.IsNullOrEmpty(sCategory))
{
GUI.color = Color.gray;
GUILayout.Label(sCategory+"/");
GUI.color = Color.white;
}
GUILayout.Label(sKey);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
void OnGUI_NewOrExistingCategory()
{
//--[ Create Category ]------------------------
GUILayout.BeginHorizontal();
mNewCategory = GUILayout.TextField(mNewCategory, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
if (GUILayout.Button("Create", "toolbarbutton", GUILayout.Width(60)))
{
EditorApplication.update += AssignCategoryToSelectedTerms;
}
GUILayout.EndHorizontal();
//--[ Existing Category ]------------------------
int Index = 0;
List<string> Categories = LocalizationManager.GetCategories();
for (int i=0, imax=Categories.Count; i<imax; ++i)
if (Categories[i].ToLower().Contains(mNewCategory.ToLower()))
{
Index = i;
break;
}
GUILayout.BeginHorizontal();
int NewIndex = EditorGUILayout.Popup(Index, Categories.ToArray(), EditorStyles.toolbarPopup, GUILayout.ExpandWidth(true));
if (NewIndex!=Index)
mNewCategory = Categories[ NewIndex ];
if (GUILayout.Button("Use", "toolbarbutton", GUILayout.Width(60)))
{
mNewCategory = Categories[ NewIndex ];
EditorApplication.update += AssignCategoryToSelectedTerms;
}
GUILayout.EndHorizontal();
}
#endregion
#region Assigning Category
public static Dictionary<string, string> TermReplacements;
void AssignCategoryToSelectedTerms()
{
mIsParsing = true;
EditorApplication.update -= AssignCategoryToSelectedTerms;
mNewCategory = mNewCategory.Trim (LanguageSourceData.CategorySeparators);
if (mNewCategory==LanguageSourceData.EmptyCategory)
mNewCategory = string.Empty;
TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
for (int i=mSelectedKeys.Count-1; i>=0; --i)
{
string sKey, sCategory;
string OldTerm = mSelectedKeys[i];
LanguageSourceData.DeserializeFullTerm( OldTerm, out sKey, out sCategory );
if (!string.IsNullOrEmpty(mNewCategory))
sKey = string.Concat(mNewCategory, "/", sKey);
if (OldTerm == sKey)
continue;
TermReplacements[ OldTerm ] = sKey;
if (!mLanguageSource.ContainsTerm(sKey))
{
TermData termData = mLanguageSource.GetTermData( OldTerm );
if (termData != null)
termData.Term = sKey;
else
TermReplacements.Remove (OldTerm);
mLanguageSource.Editor_SetDirty();
}
}
if (TermReplacements.Count<=0)
{
ShowError ("Unable to assign category: Terms were not found in the selected LanguageSource");
}
else
{
mLanguageSource.UpdateDictionary(true);
ExecuteActionOnSelectedScenes( ReplaceTermsInCurrentScene );
ParseTerms(true, false, true);
if (string.IsNullOrEmpty(mNewCategory))
mNewCategory = LanguageSourceData.EmptyCategory;
if (!mSelectedCategories.Contains(mNewCategory))
mSelectedCategories.Add (mNewCategory);
//RemoveUnusedCategoriesFromSelected();
ScheduleUpdateTermsToShowInList();
}
TermReplacements = null;
mIsParsing = false;
}
public static void ReplaceTermsInCurrentScene()
{
Localize[] Locals = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize));
if (Locals==null)
return;
bool changed = false;
for (int i=0, imax=Locals.Length; i<imax; ++i)
{
Localize localize = Locals[i];
if (localize==null || localize.gameObject==null || !GUITools.ObjectExistInScene(localize.gameObject))
continue;
string NewTerm;
if (TermReplacements.TryGetValue(localize.Term, out NewTerm))
{
localize.mTerm = NewTerm;
changed = true;
}
if (TermReplacements.TryGetValue(localize.SecondaryTerm, out NewTerm))
{
localize.mTermSecondary = NewTerm;
changed = true;
}
}
if (changed)
Editor_SaveScene(true);
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,190 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
List<string> mCharSetTool_Languages = new List<string>();
string mCharSet = string.Empty;
bool mCharSetTool_CaseSensitive;
#endregion
#region GUI Generate Script
void OnGUI_Tools_CharSet()
{
bool computeSet = false;
// remove missing languages
for (int i=mCharSetTool_Languages.Count-1; i>=0; --i)
{
if (mLanguageSource.GetLanguageIndex(mCharSetTool_Languages[i])<0)
mCharSetTool_Languages.RemoveAt(i);
}
GUILayout.BeginHorizontal (EditorStyles.toolbar);
GUILayout.Label ("Languages:", EditorStyles.miniLabel, GUILayout.ExpandWidth(true));
if (GUILayout.Button ("All", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
mCharSetTool_Languages.Clear ();
mCharSetTool_Languages.AddRange (mLanguageSource.mLanguages.Select(x=>x.Name));
computeSet = true;
}
if (GUILayout.Button ("None", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
mCharSetTool_Languages.Clear ();
computeSet = true;
}
if (GUILayout.Button ("Invert", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
var current = mCharSetTool_Languages.ToList ();
mCharSetTool_Languages.Clear ();
mCharSetTool_Languages.AddRange (mLanguageSource.mLanguages.Select(x=>x.Name).Where(j=>!current.Contains(j)));
computeSet = true;
}
GUILayout.EndHorizontal ();
//--[ Language List ]--------------------------
GUI.backgroundColor = Color.Lerp(GUITools.LightGray, Color.white, 0.5f);
mScrollPos_Languages = GUILayout.BeginScrollView( mScrollPos_Languages, LocalizeInspector.GUIStyle_OldTextArea, GUILayout.MinHeight (100), GUILayout.MaxHeight(Screen.height), GUILayout.ExpandHeight(false));
GUI.backgroundColor = Color.white;
for (int i=0, imax=mLanguageSource.mLanguages.Count; i<imax; ++i)
{
GUILayout.BeginHorizontal();
var language = mLanguageSource.mLanguages[i].Name;
bool hasLanguage = mCharSetTool_Languages.Contains(language);
bool newValue = GUILayout.Toggle (hasLanguage, "", "OL Toggle", GUILayout.ExpandWidth(false));
GUILayout.Label(language);
GUILayout.EndHorizontal();
if (hasLanguage != newValue)
{
if (newValue)
mCharSetTool_Languages.Add(language);
else
mCharSetTool_Languages.Remove(language);
computeSet = true;
}
}
GUILayout.EndScrollView();
//GUILayout.Space (5);
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
GUI.backgroundColor = Color.white;
EditorGUILayout.HelpBox("This tool shows all characters used in the selected languages", MessageType.Info);
GUILayout.Space (5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUI.changed = false;
mCharSetTool_CaseSensitive = GUILayout.Toggle(mCharSetTool_CaseSensitive, "Case-Sensitive", GUILayout.ExpandWidth(false));
if (GUI.changed)
computeSet = true;
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.Space (5);
if (computeSet)
UpdateCharSets();
int numUsedChars = string.IsNullOrEmpty (mCharSet) ? 0 : mCharSet.Length;
GUILayout.Label ("Used Characters: (" + numUsedChars+")");
EditorGUILayout.TextArea (mCharSet ?? "");
GUILayout.BeginHorizontal ();
GUILayout.FlexibleSpace ();
if (GUILayout.Button ("Copy To Clipboard", GUITools.DontExpandWidth))
EditorGUIUtility.systemCopyBuffer = mCharSet;
GUILayout.EndHorizontal ();
GUILayout.EndVertical ();
}
#endregion
#region Generate Char Set
void UpdateCharSets ()
{
mCharSet = "";
var sb = new HashSet<char> ();
var LanIndexes = new List<int> ();
for (int i=0; i<mLanguageSource.mLanguages.Count; ++i)
if (mCharSetTool_Languages.Contains(mLanguageSource.mLanguages[i].Name))
LanIndexes.Add(i);
foreach (var termData in mLanguageSource.mTerms)
{
for (int i=0; i<LanIndexes.Count; ++i)
{
int iLanguage = LanIndexes[i];
bool isRTL = LocalizationManager.IsRTL( mLanguageSource.mLanguages[iLanguage].Code );
AppendToCharSet( sb, termData.Languages[iLanguage], isRTL );
}
}
var bytes = Encoding.UTF8.GetBytes( sb.ToArray().OrderBy(c => c).ToArray() );
mCharSet = Encoding.UTF8.GetString(bytes);
}
void AppendToCharSet( HashSet<char> sb, string text, bool isRTL )
{
if (string.IsNullOrEmpty (text))
return;
text = RemoveTagsPrefix(text, "[i2p_");
text = RemoveTagsPrefix(text, "[i2s_");
if (isRTL)
text = RTLFixer.Fix( text );
foreach (char c in text)
{
if (!mCharSetTool_CaseSensitive)
{
sb.Add(char.ToLowerInvariant(c));
sb.Add(char.ToUpperInvariant(c));
}
else
sb.Add(c);
}
}
// Given "[i2p_" it removes all tags that start with that (e.g. [i2p_Zero] [i2p_One], etc)
string RemoveTagsPrefix(string text, string tagPrefix)
{
int idx = 0;
while (idx < text.Length)
{
idx = text.IndexOf(tagPrefix);
if (idx < 0)
break;
int idx2 = text.IndexOf(']', idx);
if (idx2 < 0)
break;
text = text.Remove(idx, idx2 - idx+1);
}
return text;
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
#endregion
#region GUI
void OnGUI_Tools_MergeTerms()
{
OnGUI_ScenesList(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 (5);
EditorGUILayout.HelpBox("This option replace all occurrences of this key in the selected scenes", MessageType.Info);
GUILayout.Space (5);
GUITools.CloseHeader();
OnGUI_Tools_Categorize_Terms();
OnGUI_NewOrExistingTerm();
}
void OnGUI_NewOrExistingTerm()
{
if (mKeyToExplore==null)
mKeyToExplore = string.Empty;
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
GUI.backgroundColor = Color.white;
GUILayout.Space(5);
GUILayout.Label("Replace By:");
GUILayout.EndVertical();
//--[ Create Term ]------------------------
GUILayout.BeginHorizontal();
mKeyToExplore = GUILayout.TextField(mKeyToExplore, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
if (GUILayout.Button("Create", "toolbarbutton", GUILayout.Width(60)))
{
LanguageSourceData.ValidateFullTerm( ref mKeyToExplore );
EditorApplication.update += ReplaceSelectedTerms;
}
GUILayout.EndHorizontal();
//--[ Existing Term ]------------------------
int Index = 0;
List<string> Terms = mLanguageSource.GetTermsList();
for (int i=0, imax=Terms.Count; i<imax; ++i)
if (Terms[i].ToLower().Contains(mKeyToExplore.ToLower()))
{
Index = i;
break;
}
GUILayout.BeginHorizontal();
int NewIndex = EditorGUILayout.Popup(Index, Terms.ToArray(), EditorStyles.toolbarPopup, GUILayout.ExpandWidth(true));
if (NewIndex != Index)
{
SelectTerm (Terms [NewIndex]);
ClearErrors();
}
if (GUILayout.Button("Use", "toolbarbutton", GUILayout.Width(60)))
{
SelectTerm( Terms[ NewIndex ] );
EditorApplication.update += ReplaceSelectedTerms;
}
GUILayout.EndHorizontal();
}
#endregion
#region Merge Terms
void ReplaceSelectedTerms()
{
EditorApplication.update -= ReplaceSelectedTerms;
if (string.IsNullOrEmpty(mKeyToExplore))
return;
mIsParsing = true;
string sNewKey = mKeyToExplore;
//--[ Create new Term ]-----------------------
if (mLanguageSource.GetTermData(sNewKey)==null)
{
TermData termData = AddLocalTerm(sNewKey);
//--[ Copy the values from any existing term if the target is a new term
TermData oldTerm = null;
for (int i=0, imax=mSelectedKeys.Count; i<imax; ++i)
{
oldTerm = mLanguageSource.GetTermData(mSelectedKeys[i]);
if (oldTerm!=null) break;
}
if (oldTerm!=null)
{
termData.TermType = oldTerm.TermType;
termData.Description = oldTerm.Description;
Array.Copy(oldTerm.Languages, termData.Languages, oldTerm.Languages.Length);
}
}
//--[ Delete the selected Terms from the source ]-----------------
TermReplacements = new Dictionary<string, string>(StringComparer.Ordinal);
for (int i=mSelectedKeys.Count-1; i>=0; --i)
{
string OldTerm = mSelectedKeys[i];
if (OldTerm == sNewKey)
continue;
TermReplacements[ OldTerm ] = mKeyToExplore;
DeleteTerm(OldTerm);
}
ExecuteActionOnSelectedScenes( ReplaceTermsInCurrentScene );
DoParseTermsInCurrentScene();
//--[ Update Selected Categories ]-------------
string mNewCategory = LanguageSourceData.GetCategoryFromFullTerm(sNewKey);
if (mNewCategory == string.Empty)
mNewCategory = LanguageSourceData.EmptyCategory;
if (!mSelectedCategories.Contains(mNewCategory))
mSelectedCategories.Add (mNewCategory);
//RemoveUnusedCategoriesFromSelected();
ScheduleUpdateTermsToShowInList();
TermReplacements = null;
mIsParsing = false;
}
void RemoveUnusedCategoriesFromSelected()
{
List<string> Categories = LocalizationManager.GetCategories();
for (int i=mSelectedCategories.Count-1; i>=0; --i)
if (!Categories.Contains( mSelectedCategories[i] ))
mSelectedCategories.RemoveAt(i);
if (mSelectedCategories.Count == 0)
mSelectedCategories.AddRange(Categories);
ScheduleUpdateTermsToShowInList();
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,163 @@
using System.Collections.Generic;
using TMPro;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
namespace TEngine.Localization
{
public partial class LocalizationEditor
{
#region Variables
static string _Tools_NoLocalized_Include,
_Tools_NoLocalized_Exclude;
const string _Help_Tool_NoLocalized = "This selects all labels in the current scene that don't have a Localized component.\n\nWhen Include or Exclude are set, labels will be filtered based on those settings.Separate by (,) if multiple strings are used.\n(e.g. Include:\"example,tutorial\")";
#endregion
#region GUI Find NoLocalized Terms
void OnGUI_Tools_NoLocalized()
{
//OnGUI_ScenesList();
if (_Tools_NoLocalized_Include==null)
{
_Tools_NoLocalized_Include = EditorPrefs.GetString ("_Tools_NoLocalized_Include", string.Empty);
_Tools_NoLocalized_Exclude = EditorPrefs.GetString ("_Tools_NoLocalized_Exclude", string.Empty);
}
GUILayout.Space (5);
GUI.backgroundColor = Color.Lerp (Color.gray, Color.white, 0.2f);
GUILayout.BeginVertical(LocalizeInspector.GUIStyle_OldTextArea, GUILayout.Height(1));
GUI.backgroundColor = Color.white;
EditorGUILayout.HelpBox(_Help_Tool_NoLocalized, MessageType.Info);
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.Label ("Include:", GUILayout.Width(60));
_Tools_NoLocalized_Include = EditorGUILayout.TextArea(_Tools_NoLocalized_Include, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label ("Exclude:", GUILayout.Width(60));
_Tools_NoLocalized_Exclude = EditorGUILayout.TextArea(_Tools_NoLocalized_Exclude, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
GUILayout.Space (5);
GUILayout.BeginHorizontal ();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Select No Localized Labels"))
EditorApplication.update += SelectNoLocalizedLabels;
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
#endregion
#region Find No Localized
void SelectNoLocalizedLabels()
{
EditorPrefs.SetString ("_Tools_NoLocalized_Include", _Tools_NoLocalized_Include);
EditorPrefs.SetString ("_Tools_NoLocalized_Exclude", _Tools_NoLocalized_Exclude);
EditorApplication.update -= SelectNoLocalizedLabels;
List<Component> labels = new List<Component>();
TextMesh[] textMeshes = (TextMesh[])Resources.FindObjectsOfTypeAll(typeof(TextMesh));
if (textMeshes!=null && textMeshes.Length>0)
labels.AddRange(textMeshes);
#if NGUI
UILabel[] uiLabels = (UILabel[])Resources.FindObjectsOfTypeAll(typeof(UILabel));
if (uiLabels!=null && uiLabels.Length>0)
labels.AddRange(uiLabels);
#endif
Text[] uiTexts = (Text[])Resources.FindObjectsOfTypeAll(typeof(Text));
if (uiTexts!=null && uiTexts.Length>0)
labels.AddRange(uiTexts);
#if TextMeshPro
TextMeshPro[] tmpText = (TextMeshPro[])Resources.FindObjectsOfTypeAll(typeof(TextMeshPro));
if (tmpText!=null && tmpText.Length>0)
labels.AddRange(tmpText);
TextMeshProUGUI[] uiTextsUGUI = (TextMeshProUGUI[])Resources.FindObjectsOfTypeAll(typeof(TextMeshProUGUI));
if (uiTextsUGUI!=null && uiTextsUGUI.Length>0)
labels.AddRange(uiTextsUGUI);
#endif
#if TK2D
tk2dTextMesh[] tk2dTM = (tk2dTextMesh[])Resources.FindObjectsOfTypeAll(typeof(tk2dTextMesh));
if (tk2dTM!=null && tk2dTM.Length>0)
labels.AddRange(tk2dTM);
#endif
if (labels.Count==0)
return;
string[] Includes = null;
string[] Excludes = null;
if (!string.IsNullOrEmpty (_Tools_NoLocalized_Include))
Includes = _Tools_NoLocalized_Include.ToLower().Split(',', ';');
if (!string.IsNullOrEmpty (_Tools_NoLocalized_Exclude))
Excludes = _Tools_NoLocalized_Exclude.ToLower().Split(',', ';');
List<GameObject> Objs = new List<GameObject>();
for (int i=0, imax=labels.Count; i<imax; ++i)
{
Component label = labels[i];
if (label==null || label.gameObject==null || !GUITools.ObjectExistInScene(label.gameObject))
continue;
if (labels[i].GetComponent<Localize>()!=null)
continue;
if (ShouldFilter(label.name.ToLower(), Includes, Excludes))
continue;
Objs.Add( labels[i].gameObject );
}
if (Objs.Count>0)
Selection.objects = Objs.ToArray();
else
ShowWarning("All labels in this scene have a Localize component assigned");
}
bool ShouldFilter( string Text, string[] Includes, string[] Excludes )
{
if (Includes!=null && Includes.Length>0)
{
bool hasAny = false;
for (int j=0; j<Includes.Length; ++j)
if (Text.Contains(Includes[j]))
{
hasAny = true;
break;
}
if (!hasAny)
return true;
}
if (Excludes!=null && Excludes.Length>0)
{
for (int j=0; j<Excludes.Length; ++j)
if (Text.Contains(Excludes[j]))
return true;
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 18d48e525beac1e4baff73e509fc246d
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