ã¯ããã«
èªè
ã®çæ§ããæšæ¶ã ãã®èšäºã§ã¯ã
Unity3Dç°å¢ã§äœæãããã¢ããªã±ãŒã·ã§ã³ã®ããŒã«ãªãŒãŒã·ã§ã³ã·ã¹ãã ã®äœæã«ã€ããŠèª¬æããŸãããã®ã·ã¹ãã ã¯ã
ScriptableObjectã¯ã©ã¹ã®äœ¿çšã«åºã¥ããŠãããããã¹ãã ãã§ãªãé³å£°ãç»åãããŒã«ã©ã€ãºããå€éšãããã®ãããªããŒã¿ãèªã¿èŸŒãããšãã§ããŸãã
äŒçµ±ã«ããã°ã詳现ã®èª¬æã«é²ãåã«ãããŒã«ã©ã€ãºãšã¯äœãããªãããŒã«ã©ã€ãºãå¿
èŠãªã®ãã«ã€ããŠèª¬æããŸãã
éåžžã«é »ç¹ã«ããããŠã»ãšãã©ã®å Žåãã²ãŒã éçºïŒããã³ãã®ä»ã®ã¢ããªã±ãŒã·ã§ã³ïŒã¯è€æ°ã®åžå Žã«çŠç¹ãåœãŠãŠããŸãã ååžå Žã¯ç¬èªã®èšèªã°ã«ãŒãã«ãã£ãŠç¹åŸŽä»ããããŠãããããéçºè
ã¯ãããèæ
®ã«å
¥ããå¿
èŠããããŸãããªããªããã²ãŒã ããã·ã¢èªã®ã¿ã§äœæãããšãè±èªã話ããŠãŒã¶ãŒã¯åã«äœãçè§£ã§ããªãããã§ãã ã©ããã ããã§ããã²ãŒã å
ã®è€æ°ã®èšèªã®ãµããŒããæäŸããå¿
èŠããããŸãã ã»ãšãã©ã®å Žåãããã¹ãããŒã¿ã®ã¿ã翻蚳ãããããã«ã¯
Googleã¹ãã¬ããã·ãŒããªã©ããã䜿çšãããŸãã ããŒãã«ããã®ã€ã³ããŒãã¯é£ãããªããããéåžžã«ã·ã³ãã«ã§æè»ã§ãã ãããããã¹ãŠãäžèŠãã©è²ã«èŠããããã§ã¯ãããŸããã ã²ãŒã ã«å€ãã®é³å£°ã¬ã€ãã³ã¹ãããå Žåã¯ã©ããªããŸããïŒ ãŸãã¯ãããã¹ãã¯èšèªããšã«ç°ãªããã©ã³ãã䜿çšããå¿
èŠããããŸããïŒ æåŸã«ãç»åå
ã®èšèªã«äžææ§ãå¿
èŠãšããããã¹ããäœãããããŸããïŒ ãããã®å ŽåãããŒãã«ã¯ãã¯ãååã§ã¯ãããŸããã
ããã§ãããªãã¯äœãå°ããŸããïŒãã¡ãããããªãããã§ã«çããç¥ã£ãŠããã®ã§ãªãéãïŒïŒ
ScriptableObjectãš
AssetBundleã®ãŠãŒã¹
ã±ãŒã¹ã æãã€ããŸãã ã 1ã€ç®ã¯ããŒã¿ã
Assetã®åœ¢åŒã§ä¿åããæ©èœãæäŸãã2ã€ç®ã¯ãã®ããŒã¿ãå€éšããããŒãããŠä¿åããæ©èœãæäŸããŸãã
ææ¡ãããã¢ãããŒããäœã§ããããããè©³çŽ°ã«æ€èšããŸãããã
ããŒã¿ãä¿åããæ¹æ³
ãŸããäœãã©ã®åœ¢åŒã§ä¿åããå¿
èŠããããã倿ããŸãããã®ããã«ãäžè¬ããç¹å®ã«ç§»è¡ããŸãã ããŒã«ãªãŒãŒã·ã§ã³ã·ã¹ãã ããååŸããå¿
èŠãããåºæ¬ããŒã¿ã¯ããµããŒããããŠããèšèªã®ãªã¹ãã§ãã
泚 ïŒèšäºãèªã¿é²ããªãããå¿
èŠãªã¯ã©ã¹ãäœæããŠèª¬æããŸãã ãããã£ãŠãèšèªïŒ
public class LocalizationData : ScriptableObject { public List<LanguageData> Languages; } [Serializable] public class LanguageData { public string Name { get { return _name; } } [SerializeField] private string _name; }
ãµããŒããããŠããèšèªã®ååã¯ãããŒã«ã©ã€ãºããã圢åŒã§äœ¿çšããã€ã³ã¿ãŒãã§ã€ã¹ã§ã®åºåã«äœ¿çšã§ããŸãã ã芧ã®ãšããã
LocalizationDataã¯
ScriptableObjectã®åŸç¶ã§ãããå®éããã®ã¯ã©ã¹ã¯ã¡ã€ã³ããŒã¿ãŠã§ã¢ããŠã¹ã§ãããããã¯
Assetã®åœ¢åŒã§ãããžã§ã¯ãã«å«ãŸããŸãã
次ã¯ïŒ ãããŠãåèšèªã«ã€ããŠãã¢ããªã±ãŒã·ã§ã³ãŸãã¯ã²ãŒã ã§äœ¿çšãããæçµããŒã¿ã§ãããªãœãŒã¹ã®ã»ãããä¿åããå¿
èŠããããŸãã ãŸãã䜿çšãããªãœãŒã¹ã®ã¿ã€ããæ±ºå®ããåæããŸãïŒ
enum ïŒïŒ
public enum LocalizationResourceType { Text, Image, Texture, Audio }
ç»åã¯ãUnity GUIããŒã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ãŸãã¯2Dã²ãŒã ã§äœ¿çšãã
ã¹ãã©ã€ãã§ãã ãªã
Textureãšåé¢ãããŠããã®ã§ããïŒ å©äŸ¿æ§ã®ããã ãã«ã
ããã§ããªãœãŒã¹ãžã®ãªã³ã¯ãçŽæ¥ä¿åããå Žæã決å®ããŸãã [Serializable] public class LocalizationResource { public string Tag { get { return _tag; } } public string StringData { get { return _stringData; } } public Font FontData { get { return _fontData; } } public Sprite SpriteData { get { return _spriteData; } } public Texture TextureData { get { return _textureData; } } public AudioClip AudioData { get { return _audioData; } } [SerializeField] private string _tag; [SerializeField] private string _stringData; [SerializeField] private Font _fontData; [SerializeField] private Sprite _spriteData; [SerializeField] private Texture _textureData; [SerializeField] private AudioClip _audioData; }
ã芧ã®ããã«ãã¯ã©ã¹ã«ã¯ãã¹ãŠã®å¯èœãªã¿ã€ãã®ãªãœãŒã¹ãžã®ãªã³ã¯ãå«ãŸããŠããŸãããå¿é
ããå¿
èŠã¯ãããŸãããå®éã«ã¯ããããã®ãªã³ã¯ã®1ã€ã ããæå¹ã§ãïŒãã¡ããããªãœãŒã¹ãçµåããããã«ã³ãŒããæžãããšã劚ãããã®ã¯ãããŸããïŒã å¯äžã®äŸå€ã¯ããã¹ããšãã©ã³ãã§ããããããã¯äžç·ã«ååšã§ããŸãã ãã®åäœãããŒã¿ãšãã£ã¿ãŒã®ã¬ãã«ã«å°éããããã«ããŸãïŒããã«ã€ããŠã¯ä»¥äžã§èª¬æããŸãïŒã ç¹ã«ããªãœãŒã¹ãå±ããã¿ã°ãããã«ç€ºãããŸãã ã¿ã°ãšã¯æ¬¡ã®ãšããã§ãã äžèšãèæ
®ããŠã
LanguageDataã¯ã©ã¹ã倿ŽããŸãããã
[Serializable] public class LanguageData { public string Name { get { return _name; } } public List<LocalizationResource> Resources; [SerializeField] private string _name; }
ããŒã«ãªãŒãŒã·ã§ã³ããŒã¿ãŠã§ã¢ããŠã¹ã®æåŸã®åé¡ã¯ãèšèªã«é¢ä¿ãªãããªãœãŒã¹ã®è§£éãšãã®èå¥ã§ãã ããã¯ãç¬ç«ããŠä¿åãããã¿ã°ãã·ã¹ãã ã«å°å
¥ããããšã§è§£æ±ºãããçºçããåé¡ã解決ã§ããŸãã æå®€ã§èª¬æããŸãã
[Serializable] public class LocalizationTag { public string Name { get { return _name; } } public LocalizationResourceType ResourceType { get { return _resourceType; } } [SerializeField] private string _name; [SerializeField] private LocalizationResourceType _resourceType; }
ã芧ã®ããã«ãã¿ã°ã¯ãã·ã¹ãã å
ã®ãªãœãŒã¹ãšãæçµããŒã¿ã§ã®è§£éã®ããã®ãªãœãŒã¹ã®ã¿ã€ããèå¥ããããã«äœ¿çšãããååã§ãã ãããã£ãŠãããŒã¿ãŠã§ã¢ããŠã¹ã¯æ¬¡ã®åœ¢åŒã«ãªããŸãã
public class LocalizationData : ScriptableObject { public List<LanguageData> Languages; public List<LocalizationTag> Tags; }
泚 ïŒ
LocalizationDataã«ã¯èšèªã®ãªã¹ããæ ŒçŽãããŠãããšããäºå®ã«ããããããããããè¡ã矩åã¯ãããŸããã åèšèªã¯
Assetã«ä¿åã§ããŸãã ãã®ã¢ãããŒãã§ã¯ããµãŒããŒããã®ãŠãŒã¶ãŒã®èŠæ±ã«å¿ããŠèšèªãããŠã³ããŒãã§ããŸãã
ãšãã£ã¿ãŒ
ããŒã«ãªãŒãŒã·ã§ã³ããŒã¿ãä¿åããããã®ãã¥ãŒãäœæããŸãããããã®ããŒã¿ãäœæã§ããããŒã«ãå¿
èŠã«ãªããŸããã ããã§ã¯ããšãã£ã¿ãŒã®å®å
šãªã³ãŒãã¯æäŸããŸããããã®æ¹æ³ã¯ãããŒã ã®ããŒãºãšå©äŸ¿æ§ã®åºæºã«äŸåãããããéåžžã«äž»èгçã§ãã ç§ã®ããŒãžã§ã³ã§ã¯ããã¹ãŠãéåžžã«åå§çã§ãããããŒã ã®çŸåšã®ã¿ã¹ã¯ãæºãããŠããŸãã
ãŸããäžèšã®
LocalizationDataã¯ã©ã¹ã«åºã¥ããŠ
Assetãäœæããå¿
èŠããããŸãã ãããè¡ãã«ã¯2ã€ã®æ¹æ³ããããŸãã
- éç颿°ãšMenuItem屿§ã䜿çšããŠ
- ScriptableObjectã®äžäœã¯ã©ã¹ã«çŽæ¥é©çšãããCreateAssetMenu屿§ãä»ããŠ
æåã®ãªãã·ã§ã³ã䜿çšããŸããããå®éã«ã¯éãã¯ãããŸããã
ããŒã«ãªãŒãŒã·ã§ã³ããŒã¿ã®ã¢ã»ãããäœæããæ©èœã¯æ¬¡ã®ãšããã§ãã [MenuItem("Assets/Create/Localization Data")] public static void CreateLocalizationDataAsset() { var selectionPath = AssetDatabase.GetAssetPath(Selection.activeObject); if (string.IsNullOrEmpty(selectionPath)) { selectionPath = Application.dataPath; } var path = EditorUtility.SaveFilePanelInProject( "Create Localization Data", "NewLocalizationData", "asset", string.Empty, selectionPath); if (path.Length > 0) { var asset = ScriptableObject.CreateInstance<LocalizationData>(); AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); EditorUtility.FocusProjectWindow(); Selection.activeObject = asset; } }
ã¢ã»ãããäœæãããš
ã圌ã¯ãããžã§ã¯ãã«è¡šç€ºãããç·šéã§ããããã«ãªããŸãã ãããè¡ãã«ã¯ã
LocalizationDataã¯ã©ã¹ã®
CustomEditorãäœæããŸãã ããŒã«ãªãŒãŒã·ã§ã³ã¯ããªã倧éã®ããŒã¿ã§ãããããã€ã³ã¹ãã¯ã¿ãŒã§çŽæ¥ç·šéããããšã¯ã§ããŸããããçµ±èšæ
å ±ã¯æ¬¡ã®åœ¢åŒã§è¡šç€ºã§ããŸãã

ããã§ã
[ãšãã£ã¿ãŠã£ã³ããŠã
éã ]ãã¿ã³ã䜿çšãããšãèšèªãã¿ã°ãããã³ãªãœãŒã¹ãèšå®ãããŠãã
ãšãã£ã¿ãŠã£ã³ããŠãéããŸãã ãšãã£ã¿ãŒèªäœã¯æ¬¡ã®ãšããã§ãã

ããã§ãããããã«ããã¹ãŠãéåžžã«åçŽã§ãããåæã«å¿
èŠãªããŒã¿ããã°ããç·šéããããšãã§ããŸãã ã¿ã°ãšèšèªã¯äºãã«å¥ã
ã«ç·šéãããŸãããèšèªãæ¢ã«ååšããå Žåãæ°ããã¿ã°ã远å ãããšãåãªãœãŒã¹ã远å ãããŸãã
ãšãã£ã¿ãŒã®ããã€ãã®éèŠãªç¹ã«ã€ããŠèª¬æããŸãã
- ãªãœãŒã¹ã®ã¿ã€ãã倿Žããå Žåããªã³ã¯ãååšããå Žåã¯ãªã³ã¯ãã¯ãªã¢ããããšãå¿ããªãã§ãã ãããããããªããšããªãœãŒã¹ã«å«ãŸããã¹ãã§ãªããã®ãå«ãŸããããšã«ãªãããããAssetBundleã®ãµã€ãºã®å¢å ã«ã€ãªãããŸãã
- ããã¹ãã¯éåžžã«å°ããªãŠã£ã³ããŠã«è¡šç€ºãããŸãããããã»ã©äžäŸ¿ã§ã¯ãããŸããããç·šéããããšã¯ã»ãšãã©äžå¯èœãªã®ã§ãå¥ã®ãšãã£ã¿ãŒãäœæããå¿
èŠããããŸãã
ããã¹ããšãã£ã¿ãŠã£ã³ããŠã¯æ¬¡ã®ãšããã§ãã

ãšãã£ã¿ãŒã§htmlããŒã¯ã¢ããïŒ
Unity3då
ã®
RichText ïŒããµããŒãããããšã¯ã§ããŸãããããã¯ãã¹ãŠãªãã·ã§ã³ã§ãã
ãã®ãšãã£ã¿ãŒã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã public class LocalizationTextEditorWindow : EditorWindow { public SerializedProperty CurrentTextProperty; public Font TextFont; private GenericMenu _copyPasteMenu; private GUIStyle _textStyle; public static void Show(string tag, string language, SerializedProperty textProperty, Font textFont) { var instance = (LocalizationTextEditorWindow)EditorWindow.GetWindow(typeof(LocalizationTextEditorWindow), true); instance.titleContent = new GUIContent("[{0}: {1}]".Fmt(language, tag), string.Empty); instance.CurrentTextProperty = textProperty; instance.TextFont = textFont; } private void OnEnable() { _copyPasteMenu = new GenericMenu(); _copyPasteMenu.AddItem(new GUIContent("Copy"), false, () => { EditorGUIUtility.systemCopyBuffer = CurrentTextProperty.stringValue; }); _copyPasteMenu.AddItem(new GUIContent("Paste"), false, () => { CurrentTextProperty.stringValue = EditorGUIUtility.systemCopyBuffer; CurrentTextProperty.serializedObject.ApplyModifiedProperties(); }); } private void OnGUI() { if (CurrentTextProperty == null) return; if (_textStyle == null) { _textStyle = new GUIStyle(EditorStyles.textArea); _textStyle.font = TextFont; } if (Event.current.type == EventType.MouseDown && Event.current.button == 1) { _copyPasteMenu.ShowAsContext(); } CurrentTextProperty.stringValue = GUI.TextArea(new Rect(0f, 0f, position.width, position.height), CurrentTextProperty.stringValue, _textStyle); CurrentTextProperty.serializedObject.ApplyModifiedProperties(); } }
ãã®ã³ãŒãã§æãéèŠãªç¹ã¯ããããã¡ãŒããããã¹ããã³ããŒããŠè²Œãä»ããæ©èœã§ãããã以å€ã®å Žåã¯ãã¹ãŠéåžžã«ç°¡åã§ãã
API
ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããããŒã«ãªãŒãŒã·ã§ã³ã·ã¹ãã ã®ã³ãŒãã説æããåã«ãæºããå¿
èŠãããåºæ¬çãªèŠä»¶ãå®çŸ©ããŸãã å®éã質åã¯éåžžã«äž»èгçã§ãããåéçºè
ã¯æ©èœãšãããžã§ã¯ãã«å¿ããŠç¬èªã®ã»ãããæç€ºããŸãã ç§èªèº«ãšç§ã®çµéšã«åºã¥ããŠã次ã®ãªã¹ããäœæããŸããã
- èšèªã¯ãã®å Žã§å€æŽããå¿
èŠããããŸãã ã€ãŸãããŠãŒã¶ãŒãèšèªã倿Žãããšããã«ã倿Žãããã«æå¹ã«ãªããŸãã
- ããŒã«ãªãŒãŒã·ã§ã³ããŒã¿ã¯ãè€æ°ã®ãœãŒã¹ããäœæã§ããå¿
èŠããããŸãã ã€ãŸãã1ã€ã®Assetã«ä¿åããå¿
èŠã¯ãããŸããã
ããã«åºã¥ããŠãã³ãŒãã®åœ¢æãéå§ããæåã«åºæ¬ã¯ã©ã¹ãäœæããŸãã
public class LocalizationController { public delegate void LanguageWasChanged(); public static event LanguageWasChanged OnLanguageWasChanged; }
LangaungeWasChangedã¯ãããŸããŸãªãµãã·ã¹ãã ããµãã¹ã¯ã©ã€ãããã€ãã³ãã§ãã ãã®ã€ãã³ãã¯ãèšèªã®å€æŽæã«ãªãœãŒã¹ãæŽæ°ããå¿
èŠããªãå Žæã§å¿
èŠã«ãªããŸãã
LocalizationControllerã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãã·ã³ã°ã«ãã³ããªã¢ã³ããå«ããå¿
èŠã«å¿ããŠã©ãã«ã§ãä¿åã§ããŸãã
次ã«ãå
éšããŒã¿ãŠã§ã¢ããŠã¹ãäœæããå¿
èŠããããŸãã1ã€ç®ã¯ã¿ã°ã§ã2ã€ç®ã¯ãããã«å¯Ÿå¿ãããªãœãŒã¹ã®ã¿ã€ãã§ãã
private Dictionary<string, LocalizationResourceType> _resourceTypeByTag = new Dictionary<string, LocalizationResourceType>();
ãããŠããªãœãŒã¹èªäœïŒ
private Dictionary<string, LocalizationResource> _currentResources = new Dictionary<string, LocalizationResource>();
ããã§ãã¿ã°ã«ãã£ãŠããŒã«ã©ã€ãºãªãœãŒã¹ãåãåã颿°ãå¿
èŠã§ãã ããã¯ãæåã¢ãŒãã§ããŒã¿ãååŸããããã«å¿
èŠã§ãã
public object GetResourceByTag(string tag) { if (_resourceTypeByTag.ContainsKey(tag)) { var resourceType = _resourceTypeByTag[tag]; var resource = _currentResources[tag]; switch (resourceType) { case LocalizationResourceType.Text: return new KeyValuePair<string, Font>(resource.StringData, resource.FontData); case LocalizationResourceType.Image: return resource.SpriteData; case LocalizationResourceType.Texture: return resource.TextureData; case LocalizationResourceType.Audio: return resource.AudioData; } } return null; }
ããããèšèªã倿Žããéã®èªåãªãã·ã§ã³ãšãã®å Žã§ã®ããŒã¿ã®æŽæ°ã¯ã©ãã§ããããïŒ
ãããã®ç®çã®ããã«ããµãã¹ã¯ã©ã€ããŒãªããžããªãš2ã€ã®æ¹æ³ãéå§ããŸã private Dictionary<string, List<Action<object>>> _tagHandlers = new Dictionary<string, List<Action<object>>>(); public void SubscribeTag(string tag, Action<object> handler) { if (!_tagHandlers.ContainsKey(tag)) { _tagHandlers.Add(tag, new List<Action<object>>()); } _tagHandlers[tag].Add(handler); } public void UnsubscribeTag(string tag, Action<object> handler) { if (_tagHandlers.ContainsKey(tag)) { var handlers = _tagHandlers[tag]; if (handlers.Contains(handler)) { handlers.Remove(handler); } } }
次ã«ãã¢ã»ããããããŒã¿ãèšå®ããããã®ã¡ãœããã远å ããå¿
èŠããããŸã public void SetLanguage(LanguageData language) { ClearResources(); AddResources(language.Resources); UpdateLocalizeResources(); OnLanguageWasChanged?.Invoke(); } public void AddTags(IList<LocalizationTagParameter> tags) { for (var i = 0; i < tags.Count; i++) { var tag = tags[i]; _resourceTypeByTag.Add(tag.Name, tag.ResourceType); } } public void AddResources(IList<LocalizationResource> resources) { foreach (var resource in resources) { _currentResources.Add(resource.Tag, resource); } } public void UpdateLocalizeResources() { foreach (var tag in _tagHandlers.Keys) { var resource = GetResourceByTag(tag); var handlers = _tagHandlers[tag]; foreach (var handler in handlers) { handler(resource); } } }
AddTagsã¡ãœããã¯ãã·ã¹ãã å
ã®æ¢åã®ã¿ã°ã«ã¿ã°ã远å ããŸãã
AddResourcesã¡ãœããã¯ãçŸåšã®èšèªãªãœãŒã¹ã远å ããŸãã
UpdateLocalizeResourcesã¡ãœããã¯ãèšèªå€æŽã€ãã³ãã®ãµãã¹ã¯ã©ã€ããŒã®ã¡ãœãããåŒã³åºããŸãã æåŸã«ããããšã¯ãããŒã¿ã¯ãªãŒãã³ã°ã¡ãœããã远å ããããšã§ãã
泚 ïŒ
AddTagsã¡ãœãããš
AddResourcesã¡ãœããã®äž¡æ¹ã®ãšãã£ã¿ãŒã¢ãŒãã§ã¯ãéè€ããã¿ã°åã®ãã§ãã¯ãæ¿å
¥ããå¿
èŠããããŸãã ããã¯
#if UNITY_EDITOR #endifã䜿çšããŠå®è¡ã§ããŸãã
public void ClearResources() { _currentResources.Clear(); } public void Clear() { _resourceTypeByTag.Clear(); _currentResources.Clear(); _tagHandlers.Clear(); }
ãããã£ãŠãèšè¿°ããããã¹ãŠã®ã³ãŒããèŠããšãäžè¬ã«åºç€èªäœã¯è€éã§ã¯ãªãããã¹ãŠãéåžžã«åçŽã§ãã ãã ãããã1ã€ãç¹ã«ã¿ã°ããšã«ãªãœãŒã¹ãæŽæ°ã§ããã³ã³ããŒãã³ãããããŸããã
[Serializable] public class LocalizationTagDefinition { public string Tag; private Action<object> _languageChangedHandler; public void Subsribe (Action<object> handler) { _languageChangedHandler = handler; LocalizationController.SubscribeTag(Tag, handler); } public void Unsubscribe() { LocalizationController.UnsubscribeTag(Tag, _languageChangedHandler); } }
ãã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãããŒã«ã©ã€ãºãå¿
èŠãªã€ã³ã¿ãŒãã§ã€ã¹ãŸãã¯ããŒã¿ãæäœããã¹ã¯ãªããã§äœæã§ããŸãã 䟿å®äžã
CustomPropertyDrawerã䜿çšããŠãã€ã³ã¹ãã¯ã¿ãŒçšã«å¥ã®ãšãã£ã¿ãŒãäœæã§ããŸãã ãã®ãããªãšãã£ã¿ãŒã¯æ¬¡ã®ããã«ãªããŸãã

äœ¿ãæ¹
ãã®ãããäžèšã§ã¯ãããŒã«ã©ã€ãºããŒã¿ãšããããæäœããããã«å¿
èŠãªã³ãŒããä¿åããæ¹æ³ã«ã€ããŠèª¬æããŸããã ããã§ã説æããããŒã«ãªãŒãŒã·ã§ã³ã·ã¹ãã ã䜿çšããããã®åºæ¬çãªã·ããªãªãèããŠã¿ãŸãããã
æåã®ãªãã·ã§ã³ã¯ãè€æ°ã®èšèªãä¿åãããŠãã1ã€ã®ããŒã¿ã»ãããããå Žåã®ãªãã·ã§ã³ã§ã public class GameLocalization : MonoBehaviour { public static LocalizationController Controller { get { if (_localizationController == null) { _localizationController = new LocalizationController(); } return _localizationController; } } public LocalizationData DefaultLocalization; public int DefaultLanguage; private static LocalizationController _localizationController; void Start() { if (DefaultLocalization == null) { StartCoroutine(LoadLocalizationData("http://myserver.ru/localization", (bundle) => { DefaultLocalization = bundle.LoadAllAssets<LocalizationData>()[0]; InitLanguage(); bundle.Unload(true); })); }else { InitLanguage(); } } public void ChangeLanguage(int languageId) { Controller.SetLanguage(DefaultLocalization.Languages[languageId]); } public List<string> GetLanguages() { var languages = new List<string>(); for (var i = 0; i < DefaultLocalization.Languages.Count; i++) { languages.Add(DefaultLocalization.Languages[i].Name); } return languages; } IEnumerator LoadLocalizationData(string url, Action<AssetBundle> result) { var request = UnityWebRequestAssetBundle.GetAssetBundle(url); yield return request.SendWebRequest(); var assetBundle = DownloadHandlerAssetBundle.GetContent(request); result(assetBundle); request.Dispose(); } private void InitLanguage() { Controller.AddTags(DefaultLocalization.Tags); Controller.SetLanguage(DefaultLocalization.Languages[DefaultLanguage]); } }
ååŸãããã®ïŒæåã«ãããŒã«ã©ã€ãº
ã¢ã»ãããã€ã³ã¹ããŒã«ãããŠãããã©ããã確èªããã€ã³ã¹ããŒã«ãããŠããå Žåã¯ãããŒã«ãªãŒãŒã·ã§ã³ã³ã³ãããŒã©ãŒãåæåããããã©ã«ãã®èšèªãèšå®ããŸããããã§ãªãå Žåã¯ããµãŒããŒãã
ã¢ã»ãããèªã¿èŸŒã¿ãŸãã èšèªãèšå®ããã€ã³ã¿ãŒãã§ãŒã¹ã«è¡šç€ºããèšèªã®ãªã¹ããååŸããã«ã¯ã2ã€ã®æ¹æ³ããããŸãã
SetLanguageã¡ãœãããåŒã³åºããšãã¿ã°ã«ãããªãœãŒã¹å€æŽã®ãã¹ãŠã®ãµãã¹ã¯ã©ã€ããŒãéç¥ãåãåãããªãœãŒã¹ãæŽæ°ããŸãã
次ã«ãããŒã«ã©ã€ãºããŒã¿ãè€æ°ã®
Assetsã«æ£åšããŠããå Žåã®ãªãã·ã§ã³ãæ€èšããŸãã
ããã§ã¯ãåã®äŸããããã€ãã®æ¹æ³ã倿Žããå¿
èŠããããŸãã public LocalizationData LocalizationAudio; public LocalizationData LocalizationImage; public LocalizationData LocalizationText; public int DefaultLanguage; void Start() { Controller.AddTags(LocalizationAudio.Tags); Controller.AddTags(LocalizationImage.Tags); Controller.AddTags(LocalizationText.Tags); ChangeLanguage(DefaultLanguage); } public void ChangeLanguage(int languageId) { Controller.ClearResources(); Controller.AddResources(LocalizationAudio.Languages[languageId].Resources); Controller.AddResources(LocalizationImage.Languages[languageId].Resources); Controller.AddResources(LocalizationText.Languages[languageId].Resources); Controller.UpdateLocalizeResources(); }
説æãªãã«ãã¹ãŠãæç¢ºã«ãªã£ãŠãããšæããŸãã以åã®ããã«ã¿ã°ã远å ããã ãã§ãããæåã¢ãŒãã§ãªãœãŒã¹ã远å ãããã®åŸ
UpdateLocalizeResourceã¡ãœãããåŒã³åºããŠãã¿ã°ã®ãã¹ãŠã®ãµãã¹ã¯ã©ã€ããŒã«éç¥ãããªã¬ãŒããŸãã
çµè«ãšããŠããšã³ããã€ã³ãã§ãªãœãŒã¹ãšã¿ã°ã䜿çšããããšãã€ãŸã ã³ã³ãã³ãã¬ãã«ã§ãäŸãšããŠ
Unity GUIãã
Imageãªããžã§ã¯ããååŸããŸãã
public class LocalizeImage : MonoBehaviour { public LocalizationTagDefinition ImageTag; private void OnEnable() { ImageTag.Subsribe((data) => { GetComponent<Image>().sprite = data as Sprite; }); } private void OnDisable() { ImageTag.Unsubscribe(); } }
ããã§ã¯ãåè¿°ã®
LocalizationTagDefinitionã³ã³ããŒãã³ãã䜿çšããŸãã ãã®ã¹ã¯ãªããããªããžã§ã¯ãã«æããããšã«ãããèšèªã倿Žãããå Žåã«èªåçã«ç»åã倿ŽãããŸãã
ãããã«
çµè«ãšããŠãç§ã®çŸåšã®ç ç©¶ã«ããããã®ã¢ãããŒãã®é©çšã¯ãããŒã«ã©ã€ãºã®ç掻ã倧ãã«ä¿é²ãããšèšãããã§ãã ç§ã®ãããžã§ã¯ããéçºãããŠããã»ã°ã¡ã³ãã§ã¯ãããŸããŸãªããŒã¿ã®éãéåžžã«å€ããªã£ãŠããŸããé³å£°ãç»åãããã¹ãã®äž¡æ¹ã§ãã ãŸããã»ãšãã©ã®èšèªã¯ã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã«å«ãŸããŠãããããŠãŒã¶ãŒã®èŠæ±ã«å¿ããŠããŠã³ããŒããããŸãã ãšããããã²ãŒã ã¯èšèªã«ãã£ãŠåäœãç°ãªãå ŽåããããŸãïŒããã¯ããŒã«ã©ã€ãºããã¹ãããŒã¿ã«
jsonæååã远å ããããšã§å®çŸãããŸãïŒã ãã¡ãããã·ã¹ãã ã¯æé©ã§ã¯ãªãå¯èœæ§ããããã³ãŒããšãšãã£ã¿ãŒã®äž¡æ¹ã®é¢ã§éçºã®äœå°ããããŸãïŒç¹ã«ãããšãã°ã
Googleã¹ãã¬ããã·ãŒãããã®ããã¹ãããŒã¿ã®ã€ã³ããŒãã远å ããç®ã楜ããŸããŠãããŸãïŒããç§ã®ãããžã§ã¯ãã§ã¯ä»ã®ãšããååã§ãã
æåŸã«ãäžèšã®ã¢ãããŒãã䜿çšãããå°ããªäŸã瀺ããŸãã ããã¯ãããžã¥ã¢ã«ããžãã¯ãšãã£ã¿ã®
Panthea VSã§ã ïŒã€ããªãã®ãŒã®ã€ã³ã¹ãã¬ãŒã·ã§ã³ã¯
PlayMakerã§ãã ïŒã