如何实现Unity调试控制台的命令字符串模糊搜索
Unity调试控制台命令自动补全实现方案
需求说明
看了CS2的控制台后,想给自己开发的Unity调试控制台添加命令自动补全功能:输入前缀(比如"s")时,显示所有以该前缀开头的命令(如"survey""skills""slow")。目前已将命令存入List<DevCommands>和Dictionary<string,DevCommands>,但现有SearchForDevCommand仅支持精确匹配,无法实现模糊搜索。
现有核心代码
命令初始化代码
private void Awake() { devConsole = GetComponent<DevConsole>(); CreateConsoleCommands(); } void CreateConsoleCommands() { AllCommands = new List<DevCommands>(); SearchCommand = new Dictionary<string,DevCommands>(); string CommandName = "help"; DevCommands Help = new DevCommands(CommandName, "Shows all commands.", () => { foreach (var item in AllCommands) { DefaultLog(item.Name + ": " + item.Description); } }); AllCommands.Add(Help); SearchCommand.Add(CommandName, Help); CommandName = "clear"; DevCommands Clear = new DevCommands(CommandName, "Clears the console", () => { ConsoleLogText.text = string.Empty; }); AllCommands.Add(Clear); SearchCommand.Add("clear", Clear); CommandName = "spawn"; DevCommands Spawn = new DevCommands(CommandName, "spawns items ", () => { if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("GAME")) { SpawnProps.SpawnAll(); DefaultLog("Spawned more props."); } else { DefaultLog("Cannot be used in the main menu.", LogType.Warning); } }); AllCommands.Add(Spawn); SearchCommand.Add(CommandName, Spawn); }
现有搜索方法(仅精确匹配)
void SearchForDevCommand(string text) { if (SearchCommand.TryGetValue(ConsoleInputField.text,out DevCommands command)) { Debug.Log(command.Name); } else { Debug.Log("Can't find any command."); } }
实现自动补全的修改方案
1. 修改搜索方法,实现前缀模糊匹配
把原来的精确匹配改成从AllCommands列表中筛选以输入文本开头的命令,同时支持忽略大小写(提升用户体验):
// 返回匹配的命令列表,用于显示补全提示 List<DevCommands> GetMatchingCommands(string inputText) { if (string.IsNullOrEmpty(inputText)) return new List<DevCommands>(); // 忽略大小写的前缀匹配 return AllCommands.Where(cmd => cmd.Name.StartsWith(inputText, StringComparison.OrdinalIgnoreCase)).ToList(); } // 更新原搜索方法,同时支持补全触发 void SearchForDevCommand(string text) { var matchingCommands = GetMatchingCommands(text); if (matchingCommands.Count == 1) { // 唯一匹配,直接执行命令 ExecuteCommand(matchingCommands[0]); } else if (matchingCommands.Count > 1) { // 多个匹配,显示补全列表 ShowCommandCompletions(matchingCommands); Debug.Log($"匹配到{matchingCommands.Count}个命令:{string.Join(", ", matchingCommands.Select(cmd => cmd.Name))}"); } else { Debug.Log("找不到匹配的命令。"); } } // 新增命令执行方法(复用原有逻辑) void ExecuteCommand(DevCommands command) { command.Execute(); // 假设DevCommands类有Execute方法执行命令逻辑 Debug.Log($"执行命令:{command.Name}"); }
2. 补全提示的显示逻辑
在UI层添加下拉框/列表展示匹配的命令,示例代码如下:
// 示例:显示补全列表到UI void ShowCommandCompletions(List<DevCommands> commands) { // 清空原有列表项 completionList.Clear(); foreach (var cmd in commands) { // 创建列表项,绑定点击事件(点击后自动填充输入框并执行) var listItem = Instantiate(completionItemPrefab, completionList.transform); listItem.GetComponent<TMPro.TMP_Text>().text = $"{cmd.Name}: {cmd.Description}"; listItem.GetComponent<Button>().onClick.AddListener(() => { ConsoleInputField.text = cmd.Name; SearchForDevCommand(cmd.Name); completionList.gameObject.SetActive(false); }); } completionList.gameObject.SetActive(commands.Count > 0); }
3. 输入框实时触发补全
在输入框的OnValueChanged事件中绑定匹配逻辑,实时更新补全提示:
// 在Awake或Start中绑定事件 ConsoleInputField.onValueChanged.AddListener(input => { var matches = GetMatchingCommands(input); ShowCommandCompletions(matches); });
额外优化建议
- 支持包含匹配:如果需要输入任意字符都能匹配(比如输入"ow"匹配"slow""show"),把
StartsWith改成Contains即可。 - 排序匹配结果:按命令名称长度或使用频率排序,优先显示常用命令。
- 输入框自动填充:当只有一个匹配结果时,自动填充输入框,提升操作效率。
内容的提问来源于stack exchange,提问作者outdoorsScene
相关产品推荐
相关产品推荐

