Unity 国际化 多语言设置

很多游戏中都有语言设置选项,NGUI插件中自带了国际化脚本,但是灵活性较低,而且目前项目是UGUI,以下是修改后,以便记录。

Localization和NGUI中用法一样,挂在在一个不销毁的游戏物体上,并设置当前语言,及所有语言的陪标

 

[csharp] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //----------------------------------------------  
  2.   
  3. //----------------------------------------------  
  4.   
  5. using UnityEngine;  
  6. using System.Collections.Generic;  
  7. using UnityEngine.UI;  
  8.   
  9.   
  10. public class Localization : MonoBehaviour  
  11. {  
  12.     static Localization mInst;  
  13.   
  14.     static public Localization instance  
  15.     {  
  16.         get  
  17.         {  
  18.             if (mInst == null)  
  19.             {  
  20.                 mInst = Object.FindObjectOfType(typeof(Localization)) as Localization;  
  21.   
  22.                 if (mInst == null)  
  23.                 {  
  24.                     GameObject go = new GameObject("_Localization");  
  25.                     DontDestroyOnLoad(go);  
  26.                     mInst = go.AddComponent<Localization>();  
  27.                 }  
  28.             }  
  29.             return mInst;  
  30.         }  
  31.     }  
  32.   
  33.     public string startingLanguage;  
  34.       
  35.   
  36.     public TextAsset[] languages;  
  37.   
  38.     Dictionary<int, string> mDictionary = new Dictionary<int, string>();  
  39.     string mLanguage;  
  40.       
  41.     public string currentLanguage  
  42.     {  
  43.         get  
  44.         {  
  45.             //if (string.IsNullOrEmpty(mLanguage))  
  46.             {  
  47.                 currentLanguage = PlayerPrefs.GetString("Language");  
  48.   
  49.                 if (string.IsNullOrEmpty(mLanguage))  
  50.                 {  
  51.                     currentLanguage = startingLanguage;  
  52.   
  53.                     if (string.IsNullOrEmpty(mLanguage) && (languages != null && languages.Length > 0))  
  54.                     {  
  55.                         currentLanguage = languages[0].name;  
  56.                     }  
  57.                 }  
  58.             }  
  59.             return mLanguage;  
  60.         }  
  61.         set  
  62.         {  
  63.             if (mLanguage != value)  
  64.             {  
  65.                 startingLanguage = value;  
  66.   
  67.                 if (!string.IsNullOrEmpty(value))  
  68.                 {  
  69.                     if (languages != null)  
  70.                     {  
  71.                         for (int i = 0, imax = languages.Length; i < imax; ++i)  
  72.                         {  
  73.                             TextAsset asset = languages[i];  
  74.   
  75.                             if (asset != null && asset.name == value)  
  76.                             {  
  77.                                 Load(asset);  
  78.                                 return;  
  79.                             }  
  80.                         }  
  81.                     }  
  82.                       
  83.                     TextAsset txt = Resources.Load(value, typeof(TextAsset)) as TextAsset;  
  84.   
  85.                     if (txt != null)  
  86.                     {  
  87.                         Load(txt);  
  88.                         return;  
  89.                     }  
  90.                 }  
  91.                   
  92.                 mDictionary.Clear();  
  93.                 PlayerPrefs.DeleteKey("Language");  
  94.             }  
  95.         }  
  96.     }  
  97.   
  98.     /// <summary>  
  99.     /// Determine the starting language.  
  100.     /// </summary>  
  101.   
  102.     void Awake() { if (mInst == null) { mInst = this; DontDestroyOnLoad(gameObject); } else Destroy(gameObject); }  
  103.   
  104.     /// <summary>  
  105.     /// Start with the specified starting language.  
  106.     /// </summary>  
  107.   
  108.     void Start() { if (!string.IsNullOrEmpty(startingLanguage)) currentLanguage = startingLanguage; }  
  109.   
  110.     /// <summary>  
  111.     /// Oddly enough... sometimes if there is no OnEnable function in Localization, it can get the Awake call after UILocalize's OnEnable.  
  112.     /// </summary>  
  113.   
  114.     void OnEnable() { if (mInst == null) mInst = this; }  
  115.   
  116.     /// <summary>  
  117.     /// Remove the instance reference.  
  118.     /// </summary>  
  119.   
  120.     void OnDestroy() { if (mInst == this) mInst = null; }  
  121.   
  122.     /// <summary>  
  123.     /// Load the specified asset and activate the localization.  
  124.     /// </summary>  
  125.   
  126.     void Load(TextAsset asset)  
  127.     {  
  128.         mLanguage = asset.name;  
  129.         PlayerPrefs.SetString("Language", mLanguage);  
  130.         ByteReader reader = new ByteReader(asset);  
  131.         mDictionary = reader.ReadDictionary();  
  132.         // Broadcast("OnLocalize");  
  133.     }  
  134.      
  135.   
  136.     public string Get(int key)  
  137.     {  
  138.         string val;  
  139.         return (mDictionary.TryGetValue(key, out val)) ? val : null;  
  140.     }  
  141.   
  142. }  

 

 

 

ByteReader数据解析类,不多余解释

 

 

[csharp] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //----------------------------------------------  
  2. //            NGUI: Next-Gen UI kit  
  3. // Copyright © 2011-2012 Tasharen Entertainment  
  4. //----------------------------------------------  
  5.   
  6. using UnityEngine;  
  7. using System.Text;  
  8. using System.Collections.Generic;  
  9.   
  10. /// <summary>  
  11. /// MemoryStream.ReadLine has an interesting oddity: it doesn't always advance the stream's position by the correct amount:  
  12. /// http://social.msdn.microsoft.com/Forums/en-AU/Vsexpressvcs/thread/b8f7837b-e396-494e-88e1-30547fcf385f  
  13. /// Solution? Custom line reader with the added benefit of not having to use streams at all.  
  14. /// </summary>  
  15.   
  16. public class ByteReader  
  17. {  
  18.     byte[] mBuffer;  
  19.     int mOffset = 0;  
  20.   
  21.     public ByteReader(byte[] bytes) { mBuffer = bytes; }  
  22.     public ByteReader(TextAsset asset) { mBuffer = asset.bytes; }  
  23.   
  24.     /// <summary>  
  25.     /// Whether the buffer is readable.  
  26.     /// </summary>  
  27.   
  28.     public bool canRead { get { return (mBuffer != null && mOffset < mBuffer.Length); } }  
  29.   
  30.     /// <summary>  
  31.     /// Read a single line from the buffer.  
  32.     /// </summary>  
  33.   
  34.     static string ReadLine(byte[] buffer, int start, int count)  
  35.     {  
  36. #if UNITY_FLASH  
  37.         // Encoding.UTF8 is not supported in Flash :(  
  38.         StringBuilder sb = new StringBuilder();  
  39.   
  40.         int max = start + count;  
  41.   
  42.         for (int i = start; i < max; ++i)  
  43.         {  
  44.             byte byte0 = buffer[i];  
  45.   
  46.             if ((byte0 & 128) == 0)  
  47.             {  
  48.                 // If an UCS fits 7 bits, its coded as 0xxxxxxx. This makes ASCII character represented by themselves  
  49.                 sb.Append((char)byte0);  
  50.             }  
  51.             else if ((byte0 & 224) == 192)  
  52.             {  
  53.                 // If an UCS fits 11 bits, it is coded as 110xxxxx 10xxxxxx  
  54.                 if (++i == count) break;  
  55.                 byte byte1 = buffer[i];  
  56.                 int ch = (byte0 & 31) << 6;  
  57.                 ch |= (byte1 & 63);  
  58.                 sb.Append((char)ch);  
  59.             }  
  60.             else if ((byte0 & 240) == 224)  
  61.             {  
  62.                 // If an UCS fits 16 bits, it is coded as 1110xxxx 10xxxxxx 10xxxxxx  
  63.                 if (++i == count) break;  
  64.                 byte byte1 = buffer[i];  
  65.                 if (++i == count) break;  
  66.                 byte byte2 = buffer[i];  
  67.   
  68.                 if (byte0 == 0xEF && byte1 == 0xBB && byte2 == 0xBF)  
  69.                 {  
  70.                     // Byte Order Mark -- generally the first 3 bytes in a Windows-saved UTF-8 file. Skip it.  
  71.                 }  
  72.                 else  
  73.                 {  
  74.                     int ch = (byte0 & 15) << 12;  
  75.                     ch |= (byte1 & 63) << 6;  
  76.                     ch |= (byte2 & 63);  
  77.                     sb.Append((char)ch);  
  78.                 }  
  79.             }  
  80.             else if ((byte0 & 248) == 240)  
  81.             {  
  82.                 // If an UCS fits 21 bits, it is coded as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx   
  83.                 if (++i == count) break;  
  84.                 byte byte1 = buffer[i];  
  85.                 if (++i == count) break;  
  86.                 byte byte2 = buffer[i];  
  87.                 if (++i == count) break;  
  88.                 byte byte3 = buffer[i];  
  89.   
  90.                 int ch = (byte0 & 7) << 18;  
  91.                 ch |= (byte1 & 63) << 12;  
  92.                 ch |= (byte2 & 63) << 6;  
  93.                 ch |= (byte3 & 63);  
  94.                 sb.Append((char)ch);  
  95.             }  
  96.         }  
  97.         return sb.ToString();  
  98. #else  
  99.         return Encoding.UTF8.GetString(buffer, start, count);  
  100. #endif  
  101.     }  
  102.   
  103.     /// <summary>  
  104.     /// Read a single line from the buffer.  
  105.     /// </summary>  
  106.   
  107.     public string ReadLine()  
  108.     {  
  109.         int max = mBuffer.Length;  
  110.   
  111.         // Skip empty characters  
  112.         while (mOffset < max && mBuffer[mOffset] < 32) ++mOffset;  
  113.   
  114.         int end = mOffset;  
  115.   
  116.         if (end < max)  
  117.         {  
  118.             for (;;)  
  119.             {  
  120.                 if (end < max)  
  121.                 {  
  122.                     int ch = mBuffer[end++];  
  123.                     if (ch != '\n' && ch != '\r') continue;  
  124.                 }  
  125.                 else ++end;  
  126.   
  127.                 string line = ReadLine(mBuffer, mOffset, end - mOffset - 1);  
  128.                 mOffset = end;  
  129.                 return line;  
  130.             }  
  131.         }  
  132.         mOffset = max;  
  133.         return null;  
  134.     }  
  135.   
  136.     /// <summary>  
  137.     /// Assume that the entire file is a collection of key/value pairs.  
  138.     /// </summary>  
  139.   
  140.     public Dictionary<int, string> ReadDictionary()  
  141.     {  
  142.         Dictionary<int, string> dict = new Dictionary<int, string>();  
  143.         char[] separator = new char[] { '=' };  
  144.   
  145.         while (canRead)  
  146.         {  
  147.             string line = ReadLine();  
  148.             if (line == null) break;  
  149.  
  150. #if UNITY_FLASH  
  151.             string[] split = line.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);  
  152. #else  
  153.             string[] split = line.Split(separator, 2, System.StringSplitOptions.RemoveEmptyEntries);  
  154. #endif  
  155.   
  156.             if (split.Length == 2)  
  157.             {  
  158.                 int key = int.Parse(split[0].Trim());  
  159.                 string val = split[1].Trim();  
  160.                 dict[key] = val;  
  161.             }  
  162.         }  
  163.         return dict;  
  164.     }  
  165. }  



将UILocalize脚本挂在在Text上或者Image上,就是需要多语言切换的UI上

 

 

 

[csharp] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //----------------------------------------------  
  2.   
  3. //----------------------------------------------  
  4.   
  5. using UnityEngine;  
  6. using UnityEngine.UI;  
  7.   
  8. public class UILocalize : MonoBehaviour  
  9. {  
  10.     /// <summary>  
  11.     /// Localization key.  
  12.     /// </summary>  
  13.     public string Atlas;  
  14.     public string key;  
  15.   
  16.     string mLanguage;  
  17.     bool mStarted = false;  
  18.   
  19.     /// <summary>  
  20.     /// This function is called by the Localization manager via a broadcast SendMessage.  
  21.     /// </summary>  
  22.   
  23.     void OnLocalize(Localization loc) { if (mLanguage != loc.currentLanguage) Localize(); }  
  24.   
  25.     /// <summary>  
  26.     /// Localize the widget on enable, but only if it has been started already.  
  27.     /// </summary>  
  28.   
  29.     void OnEnable() { if (mStarted && Localization.instance != null) Localize(); }  
  30.   
  31.     /// <summary>  
  32.     /// Localize the widget on start.  
  33.     /// </summary>  
  34.   
  35.     void Start()  
  36.     {  
  37.         mStarted = true;  
  38.         if (Localization.instance != null) Localize();  
  39.     }  
  40.   
  41.     /// <summary>  
  42.     /// Force-localize the widget.  
  43.     /// </summary>  
  44.   
  45.     public void Localize(string key = null)  
  46.     {  
  47.         if (key == null)  
  48.             key = this.key;  
  49.         Localization loc = Localization.instance;  
  50.         MaskableGraphic w = GetComponent<MaskableGraphic>();  
  51.         Text lbl = w as Text;  
  52.         Image sp = w as Image;  
  53.   
  54.         // If no localization key has been specified, use the label's text as the key  
  55.         if (string.IsNullOrEmpty(mLanguage) && string.IsNullOrEmpty(key) && lbl != null)  
  56.             key = lbl.text;  
  57.   
  58.         // If we still don't have a key, use the widget's name  
  59.         string val = string.IsNullOrEmpty(key) ? w.name : loc.Get(int.Parse(key));  
  60.   
  61.         if (val != null)  
  62.         {  
  63.             if (lbl != null)  
  64.             {  
  65.                 lbl.text = val;  
  66.             }  
  67.             else if (sp != null)  
  68.             {  
  69.                 if (Atlas == null)  
  70.                     return;  
  71.                 sp.sprite = DoRo.Manager.LoadManager.Instance.LoadSprite(Atlas, val);  
  72.             }  
  73.         }  
  74.         mLanguage = loc.currentLanguage;  
  75.     }  
  76. }  

 

posted on 2017-01-10 15:55 Sun‘刺眼的博客 阅读(...) 评论(...) 编辑 收藏

导航

公告