天天看点

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组件,来解决这个问题