zoukankan      html  css  js  c++  java
  • 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 != ' ' && ch != ' ') 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. }  
  • 相关阅读:
    bootstrap模态框
    css 禁止选中文本
    Python Flask Tornado
    JS canvas标签动态绘制图型
    JS 跳转页面
    JS 计算器
    JS
    柱状图中最大的矩形
    在不使用第三个变量的情况下交换两个数的值
    springboot配置静态资源访问的2种方式
  • 原文地址:https://www.cnblogs.com/android-blogs/p/6269661.html
Copyright © 2011-2022 走看看