具体设置选项的设置 创建预制体可以减少重复的选项设置,常用的设置选项通常分为以下几种
左标签+右滑动槽
左标签+右输入框
左标签+右开关按钮
左标签+右下拉列表
左标签+右按钮
预制体设置 需要先在Day3中 中完成的ContentPanel预制体 进行一些修改
在Content 的Vertical Layout Group 组件中,找到Padding填充 ,为其添加适当的间距,这样不会紧贴画布边缘
左标签+右滑动槽
创建空对象Label_Slider
添加Text 子物体,重命名为Label ,配置自动切换字体
添加Slider 子物体
添加Horizontal Layout Group 组件,勾选Child Controls Size 的 Width 和 Height,取消勾选Child Force Expand 的 Width
在Slider 组件中
添加Layout Element 组件,勾选Preferred Width ,设置为合适值
在Label 组件中
添加Layout Element 组件,勾选Flexible Width ,设置为1(会占据剩余的所有空间)
完成预制体
左标签+右输入框
创建空对象Label_InputField
添加Text 子物体,重命名为Label ,配置自动切换字体
添加空对象子物体并重命名为Wrapper 子物体
添加Horizontal Layout Group 组件,勾选Child Controls Size 的 Width 和 Height,取消勾选Child Force Expand 的 Width
在Wrapper 子物体中
添加Input Field 子物体
添加Layout Element 组件,勾选Preferred Width ,设置为与左标签+右滑动槽 相同的值,后续为了UI统一建议都调整为相同值
在Input Field 中
控制Rect Transform 组件,调整输入框大小
在InputField->Text Area->Placeholder 中可以设置默认显示内容,可以考虑在这里设置为居中
在InputField->Text Area->Text 中可以设置用户输入的值,在此也要设置自动切换字体
在Label 组件中
添加Layout Element 组件,勾选Flexible Width ,设置为1(会占据剩余的所有空间)
完成预制体
左标签+开关按钮
创建空对象Label_Toggle
添加Text 子物体,重命名为Label ,配置自动切换字体
添加Toggle 子物体
添加Horizontal Layout Group 组件,勾选Child Controls Size 的 Width 和 Height,取消勾选Child Force Expand 的 Width
在Toggle 组件中
添加Layout Element 组件,勾选Preferred Width ,设置为合适值
删除Toggle 自带的Label 子物体
在Label 组件中
添加Layout Element 组件,勾选Flexible Width ,设置为1(会占据剩余的所有空间)
完成预制体
左标签+下拉列表
创建空对象Label_Dropdown
添加Text 子物体,设置为Label ,配置自动切换字体
添加Wrapper 子物体
添加Horizontal Layout Group 组件,勾选Child Controls Size 的 Width 和 Height,取消勾选Child Force Expand 的 Width
在Wrapper 子物体中
添加Dropdown 子物体
添加Layout Element 组件,勾选Preferred Width ,设置为合适值
在Label 组件中
添加Layout Element 组件,勾选Flexible Width ,设置为1(会占据剩余的所有空间)
完成预制体
左标签+右按钮
创建空对象Label_Button
添加Text 子物体,重命名为Label ,配置自动切换字体
添加空对象并重命名为Wrapper
添加Horizontal Layout Group 组件,勾选Child Controls Size 的 Width 和 Height,取消勾选Child Force Expand 的 Width
在Wrapper 子物体中
添加Button 子物体
添加Layout Element 组件,勾选Preferred Width ,设置为合适值
在Label 组件中
添加Layout Element 组件,勾选Flexible Width ,设置为1(会占据剩余的所有空间)
完成预制体
为具体设置编写脚本 切换语言
拖入Label_Dropdown 预制体到LanguagePanel->Content 中
在Dropdown 物体的Dropdown-TextMeshPro 组件中,添加Options,注意这里的顺序要与项目设置 里的语言顺序一致
在Day3中 中添加的SettingsManager脚本 中添加以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using UnityEngine;using UnityEngine.UI;using UnityEngine.Localization.Settings;using TMPro;public class SettingsManager : MonoBehaviour { private TMP_Dropdown languageDropdown; private void Awake () { languageDropdown = LanguagePanel.transform.Find("Content/Language/Wrapper/Dropdown" ).GetComponent<TMP_Dropdown>(); languageDropdown.onValueChanged.AddListener(OnLanguageChanged); } private void OnLanguageChanged (int index ) { if (LocalizationSettings.InitializationOperation.IsDone) { LocalizationSettings.SelectedLocale = LocalizationSettings.AvailableLocales.Locales[index]; } } }
按键绑定 默认的控制方式可能不是用户习惯的,所以需要添加按键绑定功能
用左标签+右按钮 的预制体作为按键绑定的对象
准备Excel表格 规划按键,记录按键的id 、名称 、默认按键
新建KeybindManager 脚本挂在在Canvas_Settings_Menu 上,并参考下述代码实现按键的记录,先简单阐述这一段逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 using System.Collections.Generic;using UnityEngine;[System.Serializable ] public struct CustomKeyBind{ public KeyCode MainKey; public bool RequireCtrl; public bool RequireShift; public bool RequireAlt; public override string ToString () { string s = "" ; if (RequireCtrl) s += "Ctrl + " ; if (RequireShift) s += "Shift + " ; if (RequireAlt) s += "Alt + " ; s += MainKey.ToString(); return s; } public string Serialize () { string s = "" ; if (RequireCtrl) s += "Ctrl+" ; if (RequireShift) s += "Shift+" ; if (RequireAlt) s += "Alt+" ; s += MainKey.ToString(); return s; } public static CustomKeyBind Parse (string savedStr ) { CustomKeyBind bind = new CustomKeyBind(); bind.RequireCtrl = savedStr.Contains("Ctrl+" ); bind.RequireShift = savedStr.Contains("Shift+" ); bind.RequireAlt = savedStr.Contains("Alt+" ); string [] parts = savedStr.Split('+' ); string keyStr = parts[parts.Length - 1 ]; if (System.Enum.TryParse(keyStr, out KeyCode parsedKey)) bind.MainKey = parsedKey; else bind.MainKey = KeyCode.None; return bind; } } public class KeybindManager : MonoBehaviour { public static KeybindManager Instance { get ; private set ; } public Dictionary<string , CustomKeyBind> Keybinds { get ; private set ; } private void Awake () { if (Instance != null && Instance != this ) { Destroy(gameObject); return ; } Instance = this ; Keybinds = new Dictionary<string , CustomKeyBind>(); LoadKeybinds(); } private void LoadKeybinds () { SafeLoadKeybind("MoveUp" , "W" ); SafeLoadKeybind("MoveDown" , "S" ); SafeLoadKeybind("MoveLeft" , "A" ); SafeLoadKeybind("MoveRight" , "D" ); SafeLoadKeybind("Attack" , "Mouse0" ); SafeLoadKeybind("Skill" , "Ctrl+Mouse1" ); SafeLoadKeybind("Menu" , "Escape" ); } private void SafeLoadKeybind (string actionName, string defaultKeyString ) { string savedKeyString = PlayerPrefs.GetString(actionName, defaultKeyString); CustomKeyBind bind = CustomKeyBind.Parse(savedKeyString); if (bind.MainKey == KeyCode.None) { Debug.LogWarning($"[{actionName} ] 存档已损坏,重置为: {defaultKeyString} " ); bind = CustomKeyBind.Parse(defaultKeyString); } Keybinds[actionName] = bind; } public void BindKey (string actionName, CustomKeyBind newBind ) { Keybinds[actionName] = newBind; PlayerPrefs.SetString(actionName, newBind.Serialize()); PlayerPrefs.Save(); } public bool GetActionDown (string actionName ) { if (!Keybinds.TryGetValue(actionName, out CustomKeyBind bind)) return false ; bool ctrlHeld = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); bool shiftHeld = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); bool altHeld = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt); if (bind.RequireCtrl != ctrlHeld) return false ; if (bind.RequireShift != shiftHeld) return false ; if (bind.RequireAlt != altHeld) return false ; return Input.GetKeyDown(bind.MainKey); } public bool GetAction (string actionName ) { if (!Keybinds.TryGetValue(actionName, out CustomKeyBind bind)) return false ; bool ctrlHeld = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); bool shiftHeld = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); bool altHeld = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt); if (bind.RequireCtrl != ctrlHeld) return false ; if (bind.RequireShift != shiftHeld) return false ; if (bind.RequireAlt != altHeld) return false ; return Input.GetKey(bind.MainKey); } }
新建KeybindUIItem 脚本放在按钮预制体的根节点下,并参考下述代码实现预制体中的信息读取、硬盘中已存数据读取、接收用户输入功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 using UnityEngine;using UnityEngine.UI;using TMPro;using UnityEngine.Localization;using UnityEngine.EventSystems; public class KeybindUIItem : MonoBehaviour { [Header("绑定设置" ) ] public string actionName; [Header("UI 组件引用" ) ] public TextMeshProUGUI labelText; public Button bindButton; public TextMeshProUGUI buttonText; [Header("多语言文本配置" ) ] public LocalizedString waitingInputString; private bool isWaitingForInput = false ; private static KeybindUIItem currentActiveItem = null ; private void Start () { bindButton.onClick.AddListener(StartListening); UpdateButtonText(); } private void StartListening () { if (currentActiveItem != null && currentActiveItem != this ) { currentActiveItem.CancelListening(); } currentActiveItem = this ; if (EventSystem.current != null ) { EventSystem.current.SetSelectedGameObject(null ); } isWaitingForInput = true ; buttonText.text = waitingInputString.GetLocalizedString(); } public void CancelListening () { isWaitingForInput = false ; UpdateButtonText(); } private void OnGUI () { if (!isWaitingForInput) return ; Event e = Event.current; if (e.isMouse && e.type == EventType.MouseDown) { CustomKeyBind newBind = new CustomKeyBind { RequireCtrl = e.control, RequireShift = e.shift, RequireAlt = e.alt, MainKey = KeyCode.Mouse0 + e.button }; FinishBinding(newBind); e.Use(); return ; } if (e.isKey && e.keyCode != KeyCode.None) { if (e.type == EventType.KeyDown) { if (IsModifierKey(e.keyCode)) { string tempStr = "" ; if (e.control) tempStr += "Ctrl + " ; if (e.shift) tempStr += "Shift + " ; if (e.alt) tempStr += "Alt + " ; buttonText.text = tempStr; return ; } CustomKeyBind newBind = new CustomKeyBind { RequireCtrl = e.control, RequireShift = e.shift, RequireAlt = e.alt, MainKey = e.keyCode }; FinishBinding(newBind); e.Use(); } else if (e.type == EventType.KeyUp) { if (IsModifierKey(e.keyCode)) { CustomKeyBind newBind = new CustomKeyBind { RequireCtrl = false , RequireShift = false , RequireAlt = false , MainKey = e.keyCode }; FinishBinding(newBind); e.Use(); } } } } private void FinishBinding (CustomKeyBind bind ) { KeybindManager.Instance.BindKey(actionName, bind); isWaitingForInput = false ; if (currentActiveItem == this ) { currentActiveItem = null ; } UpdateButtonText(); } private void UpdateButtonText () { if (KeybindManager.Instance.Keybinds.ContainsKey(actionName)) { buttonText.text = KeybindManager.Instance.Keybinds[actionName].ToString(); } } private bool IsModifierKey (KeyCode code ) { return code == KeyCode.LeftControl || code == KeyCode.RightControl || code == KeyCode.LeftShift || code == KeyCode.RightShift || code == KeyCode.LeftAlt || code == KeyCode.RightAlt || code == KeyCode.LeftCommand || code == KeyCode.RightCommand; } }
完善翻译问题
用Excel解决翻译问题 可以将Localization Tables 导出为Excel 表格,从而完成翻译工作
Window->Asset Management Tools->Localization Tables
切换到String Table ,点击右上角的小三点,选择**Export->CSV…**选择导出路径
打开导出的Excel 表格,即可开始翻译,翻译完成后再重新导入即可