天天看點

GameFramework---本地化功能(六)一、正常用法二、實踐

特别提示: 本系列基于Unity 2019.4.8,架構版本GameFramework 2021.05.31

本系列部落格位址: 傳送門

Game Framework提供了本地化功能,也就是我們平時所說的多語言。Game Framework 在本地化方面,不但支援文本的本地化,還支援任意資源的本地化,比如遊戲中釋放煙花特效也可以做出幾個多國語言的版本,使得中文版裡是“新年好”字樣的特效,而英文版裡是“Happy New Year”字樣的特效。

一、正常用法

擷取本地化元件

讀取字典

public void  ReadData(string dictionaryAssetName) 
public void  ReadData(string dictionaryAssetName, int priority) 
public void  ReadData(string dictionaryAssetName, object userData) 
public void  ReadData(string dictionaryAssetName, int priority, object userData) 
           

解析字典

public bool ParseData(string dictionaryString)
public bool ParseData(string dictionaryString, object userData)
public bool ParseData(byte[] dictionaryBytes)
public bool ParseData(byte[] dictionaryBytes, object userData)
public bool ParseData(byte[] dictionaryBytes, int startIndex, int length)
public bool ParseData(byte[] dictionaryBytes, int startIndex, int length, object userData)
           

根據字典主鍵擷取字典内容字元串

public string GetString(string key)
public string GetString(string key, object arg0)
public string GetString(string key, object arg0, object arg1)
public string GetString(string key, object arg0, object arg1, object arg2)
public string GetString(string key, params object[] args)
public string GetRawString(string key)
           

二、實踐

1、注意事項

Localization有個預設輔助器,裡面幫我們寫了ReadData,ParseData,但是這并不能滿足我們的資料解析需求,是以我寫了一個Json的,為什麼不寫XML的,因為官方示例寫了一個XML的(以後會說),為了有所差別以及加深了解

GameFramework---本地化功能(六)一、正常用法二、實踐
using GameFramework;
using GameFramework.Localization;
using LitJson;
using System;
using UnityGameFramework.Runtime;

public class JsonLocalizationHelper : DefaultLocalizationHelper
{
	public override bool ParseData(ILocalizationManager localizationManager, string dictionaryString, object userData)
	{
		try
		{
			string currentLanguage = Component.Localization.Language.ToString();

			//GF内置的Json解析不出來,暫未深究其原因
			//Root root = Utility.Json.ToObject<Root>(dictionaryString);
			Root root = JsonMapper.ToObject<Root>(dictionaryString);
			foreach (var item in root.Dictionaries.DictionaryItem)
			{
				string language = item.Language;

				if (language != currentLanguage)
				{
					continue;
				}
				foreach (var item1 in item.StringItem)
				{
					if (!localizationManager.AddRawString(item1.Key, item1.Value))
					{
						Log.Warning("Can not add raw string with key '{0}' which may be invalid or duplicate.", item1.Key);
						return false;
					}
				}
			}

			return true;
		}
		catch (Exception exception)
		{
			Log.Warning("Can not parse dictionary data with exception '{0}'.", exception.ToString());
			return false;
		}
	}
}

           

主要功能就是将讀到的json通過固定格式解析出來,并且存到localizationManager管理器的字典中

在寫的時候遇到一個問題,GF自帶的Utility.Json解析失敗,是以改用了LitJson,這個問題以後再深究,這裡暫時先跳過

2、目标

此階段demo目标是完成Menu和Setting的多語言切換,是以我又對我們的demo加了億點點細節(嘿嘿嘿…),先來測試一下上述中我們的資料解析是否通過,目前隻有中文跟英文兩個版本資料

當Language為中文時

GameFramework---本地化功能(六)一、正常用法二、實踐

當Language為英文時

GameFramework---本地化功能(六)一、正常用法二、實踐

3、億點點細節

  • 增加中文與英文Localization資料
//中文
{
  "Dictionaries": {
    "DictionaryItem":[ {
      "Language": "ChineseSimplified",
      "StringItem": [
        {
          "Key": "Menu.StartButton",
          "Value": "開始"
        },
        {
          "Key": "Menu.SettingButton",
          "Value": "設定"
        },
        {
          "Key": "Setting.Music",
          "Value": "背景音樂"
        },
        {
          "Key": "Setting.Sound",
          "Value": "遊戲音效"
        },
        {
          "Key": "Setting.UISound",
          "Value": "界面音效"
        },
        {
          "Key": "Setting.Language",
          "Value": "遊戲語言"
        },
          {
            "Key": "Language.English",
            "Value": "英語"
          },
          {
            "Key": "Language.ChineseSimplified",
            "Value": "中文"
          },
         {
          "Key": "Setting.ConfirmButton",
          "Value": "确定"
        }, {
          "Key": "Setting.CancelButton",
          "Value": "取消"
        },
        {
          "Key": "Setting.LanguageTips",
          "Value": "更改語言需要重新開機遊戲"
        }
      ]
    }
    ]
  }
}
           
//英文
{
  "Dictionaries": {
    "DictionaryItem":[ {
      "Language": "English",
      "StringItem": [
        {
          "Key": "Menu.StartButton",
          "Value": "START"
        },
        {
          "Key": "Menu.SettingButton",
          "Value": "SETTINGS"
        },
        {
          "Key": "Setting.Music",
          "Value": "Music"
        },
        {
          "Key": "Setting.Sound",
          "Value": "Sound FX"
        },
        {
          "Key": "Setting.UISound",
          "Value": "UI Sound FX"
        },
        {
          "Key": "Setting.Language",
          "Value": "Language"
        },
         {
            "Key": "Language.English",
            "Value": "English"
          },
          {
            "Key": "Language.ChineseSimplified",
            "Value": "Chinese"
          },
         {
          "Key": "Setting.ConfirmButton",
          "Value": "OK"
        }, {
          "Key": "Setting.CancelButton",
          "Value": "CANCEL"
        },
        {
          "Key": "Setting.LanguageTips",
          "Value": "Language change demands restarting"
        }
      ]
    }
    ]
  }
}
           
  • 增加GFUIForm腳本,主要功能在初始化時替換不同語言文字,然後分别讓UIForm_Setting跟UIForm_Menu繼承GFUIForm腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using UnityEngine.UI;
public class GFUIForm : UIFormLogic
{


   /// <summary>
   /// 界面初始化
   /// </summary>
   /// <param name="userData"></param>
   protected override void OnInit(object userData)
   {
   	base.OnInit(userData);

   	Text[] texts = GetComponentsInChildren<Text>(true);
   	for (int i = 0; i < texts.Length; i++)
   	{
   		if (!string.IsNullOrEmpty(texts[i].text))
   		{
   			texts[i].text = Component.Localization.GetString(texts[i].text);
   		}
   	}

   }
   /// <summary>
   /// 界面打開
   /// </summary>
   /// <param name="userData"></param>
   protected override void OnOpen(object userData)
   {
   	base.OnOpen(userData);


   }

   /// <summary>
   /// 界面關閉
   /// </summary>
   /// <param name="isShutdown"></param>
   /// <param name="userData"></param>
   protected override void OnClose(bool isShutdown, object userData)
   {
   	base.OnClose(isShutdown, userData);


   }
   public void Close()
   {
   	Component.UI.CloseUIForm(this.UIForm);
   }
}

           
  • 完善UIForm_Setting腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using UnityEngine.UI;
using GameFramework.Localization;

public class UIForm_Setting : GFUIForm
{
   public Button Btn_Confirm;
   public Button Btn_Cancel;


   public Toggle Toggle_Music;
   public Slider Slider_Music;
   public Toggle Toggle_SoundEffect;
   public Slider Slider_SoundEffect;
   public Toggle Toggle_UISoundEffect;
   public Slider Slider_UISoundEffect;

   public Toggle m_EnglishToggle = null;
   public Text Text_LanguageTips;
   public Toggle m_ChineseSimplifiedToggle = null;
   private Language m_SelectedLanguage = Language.Unspecified;

   /// <summary>
   /// 界面初始化
   /// </summary>
   /// <param name="userData"></param>
   protected override void OnInit(object userData)
   {
   	base.OnInit(userData);

   	Btn_Cancel.onClick.AddListener(() =>
   	{
   		Component.UI.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default");
   		Close();
   	});

   }



   /// <summary>
   /// 界面打開
   /// </summary>
   /// <param name="userData"></param>
   protected override void OnOpen(object userData)
   {
   	base.OnOpen(userData);
   	Log.Error($"眼睛一睜,{Name}就打開了");
   	m_SelectedLanguage = Component.Localization.Language;
   	switch (m_SelectedLanguage)
   	{
   		case Language.English:
   			m_EnglishToggle.isOn = true;
   			break;
   		case Language.ChineseSimplified:
   			m_ChineseSimplifiedToggle.isOn = true;
   			break;
   		default:
   			break;
   	}
   }

   /// <summary>
   /// 界面關閉
   /// </summary>
   /// <param name="isShutdown"></param>
   /// <param name="userData"></param>
   protected override void OnClose(bool isShutdown, object userData)
   {
   	base.OnClose(isShutdown, userData);
   	Log.Error($"眼睛一閉,{Name}就關閉了");
   }

   public void OnEnglishSelected(bool isOn)
   {
   	if (!isOn)
   	{
   		return;
   	}

   	m_SelectedLanguage = Language.English;
   	RefreshLanguageTips();
   }

   public void OnChineseSimplifiedSelected(bool isOn)
   {
   	if (!isOn)
   	{
   		return;
   	}

   	m_SelectedLanguage = Language.ChineseSimplified;
   	RefreshLanguageTips();
   }
   private void RefreshLanguageTips()
   {
   	Text_LanguageTips.gameObject.SetActive(m_SelectedLanguage != Component.Localization.Language);
   }
   public void ClickConfirmBtn()
   {
   	if (m_SelectedLanguage == Component.Localization.Language)
   	{
   		Close();
   		Component.UI.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default");
   		return;
   	}
   	GameEntry.Shutdown(ShutdownType.Restart);
   }
}

           

到了這,我們還是無法直接在程式内切換語言版本,需要我們退出程式在編輯器手動調整,因為我們沒有儲存設定,下一章我們将講解遊戲配置SettingComponent元件,來解決這個問題