Unity中如何禁止TMP输入字段长按按键重复输入字符
解决方案1:重写TMP_InputField的输入处理(最稳定)
直接继承TMP_InputField,拦截长按产生的重复输入事件,从根源避免重复字符生成,比在Update里覆写text性能更好、逻辑更可控:
using UnityEngine; using TMPro; public class NoRepeatTMPInputField : TMP_InputField { // 记录上一次触发输入的按键码 private KeyCode lastPressedKey = KeyCode.None; protected override void LateUpdate() { // 只在输入框选中状态下处理 if (isFocused) { // 检测任意按键抬起,清空上次记录的按键 if (Input.anyKeyUp) { lastPressedKey = KeyCode.None; } } base.LateUpdate(); } // 重写输入事件处理方法 protected override void ProcessEvent(Event e) { // 只处理按键按下事件 if (e.type == EventType.KeyDown) { // 匹配退格键、普通字符、标点符号的输入 if (e.keyCode == KeyCode.Backspace || char.IsLetterOrDigit(e.character) || char.IsPunctuation(e.character)) { // 和上次按下的按键一致,说明是长按触发的重复事件,直接拦截 if (e.keyCode == lastPressedKey) { e.Use(); return; } // 记录本次按下的按键 lastPressedKey = e.keyCode; } } base.ProcessEvent(e); } }
使用方式:把场景里原来的TMP_InputField组件替换成这个自定义的NoRepeatTMPInputField即可,不需要额外写Update逻辑。
解决方案2:修复现有代码的执行顺序问题
现有代码出现重复的核心原因是:TMP的默认输入处理逻辑执行在Update之后,你在Update里保存的lastText其实已经是TMP插入了一次字符后的结果,下一帧TMP又插入了重复字符,导致最终出现重复。
只需要把逻辑移到LateUpdate里执行即可,同时补充光标位置修复逻辑避免光标跳动:
private string lastText; private bool keyPressedThisFrame = false; private void Update() { keyPressedThisFrame = false; if (IsFieldSelected && Input.anyKeyDown) { keyPressedThisFrame = true; } } private void LateUpdate() { if (!IsFieldSelected) return; if (keyPressedThisFrame) { lastText = inputField.text; } else if (Input.anyKey) { inputField.text = lastText; // 保持光标在文本末尾,避免输入过程中光标错位 inputField.caretPosition = lastText.Length; } }
可选补充
如果需要支持Ctrl+C/V、Ctrl+A等组合键操作,可以在两个方案的拦截逻辑里增加判断,排除带有Ctrl、Alt、Shift修饰符的按键即可。
内容的提问来源于stack exchange,提问作者E_Williams
相关产品推荐
相关产品推荐

