unity多语言系统

发布时间:2026/10/7 16:14:37
unity多语言系统 需要一个校验程序能找到整个项目所有text并且对每种语言json都有它的键。文本控件绑定key继承还是组合整个项目每个Text控件都有一个id。可以把Text所在的game Object名字当id或者继承Text实现一个有id的。using UnityEngine; using UnityEngine.UI; namespace MyFarm { public class LocalText:Text { [SerializeField] public string key; } }然后发现继承Text加一个key检查器也显示不出来必须自定义检查器编辑器using UnityEditor; namespace MyFarm { [CustomEditor(typeof(LocalText), true)] public class LocalTextEditor: UnityEditor.UI.TextEditor { LocalText m_Text; protected override void OnEnable() { base.OnEnable(); m_Text (LocalText)target; } public override void OnInspectorGUI() { base.OnInspectorGUI(); m_Text.key EditorGUILayout.TextField(key, m_Text.key); } } }或许这也不是最好的方案应该弄一个类require Text控件。就不用重写检查器了。考虑到继承Text需要把项目资源的Text控件一个个替换重新设置对齐、字大小、字颜色还是组合比较好using System.Reflection; using UnityEngine; using UnityEngine.UI; namespace MyFarm { [RequireComponent(typeof(Text))] public class LocalTextKey:MonoBehaviour { [SerializeField] string key; public string Key key; Text _text; Text text { get { if(_text null) { _text GetComponentText(); } return _text; } } private void Start() { UpdateText(MySettingsManager.Instance.settings.gameLanguage); MySettingsManager.Instance.onLanguageChanged UpdateText; } private void OnDestroy() { MySettingsManager.Instance.onLanguageChanged - UpdateText; } public void UpdateText(string langName) { var dic LanguageManager.Instance.LangDic; if (dic.ContainsKey(langName)) { var langSO dic[langName]; FieldInfo field langSO.GetType().GetField(key); if (field ! null) { text.text field.GetValue(langSO).ToString(); } } } } }一种语言的配置文件json还是SO每种语言一个json里面是id-文本的字典。可以用SO编辑生成json。或者直接用SO也行每个文本是作字段还是字典键值对如果作键值对每种语言还要一个个加键作为字段写好配置脚本所有语言都有这些字段。作键值对手动加键可能漏键应该使用Excel写配置文本Id作表头就不会漏键。如果作字段语言组件持有Id按字段名去查需要用反射频繁查性能不好需要把FieldInfo缓存下来。那么我们形成2种工作流作为字段SO配置作为键值对Excel配置。然后我想到第3种工作流配置时文本作为字段用SO配置但是读取时读取成字典。因为json对象字段和字典键值对看起来是一样的。这样不用反射没有性能问题。语言配置文件放哪如果想支持热更新放AB包那么一定要从配置树的某个节点记录语言配置总表的包名和资源名。语言管理器负责读取语言配置总表和单语言配置文件给其他系统取用。这里语言单独做了管理器由设置管理器调用。using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MyFarm { /// summary /// 多语言管理器。负责加载每种语言的配置文件让各处的LocalTextKey脚本根据语言设置来取用文本 /// /summary public class LanguageManager:MySingletonLanguageManager { LanguageListSO languageListSO; Dictionarystring, LanguageSO langDicnew(); public Dictionarystring, LanguageSO LangDic langDic; Liststring langList; public Liststring LangList { get { if (langList null) { langList new Liststring(langDic.Keys); } return langList; } } public LanguageManager() { languageListSO MyABManager.LoadResLanguageListSO(MyConfigManager.Instance.mainConfig.languageAB, MyConfigManager.Instance.mainConfig.languageConfigPath); foreach(var lang in languageListSO.languageSOs) { langDic[lang.name] lang; } } } }通过得到字段得到对象的字段值得到文本结果是空字符串。而且其他文本控件没问题只有一个有问题if (field null) { field langSO.GetType().GetField(key); } if (field ! null) { text.text field.GetValue(langSO).ToString();//是空字符串 }配表里的物品名称、描述如何做多语言那么配表里的名字、描述也都要写键了然后一种语言是一个字典