Unity中TextMeshPro输入框文本变更监听及替换字符栈溢出问题咨询
Unity TextMeshPro输入框字符替换栈溢出问题解决方案
异常根因
你遇到的StackOverflowException由无限递归触发:
onValueChanged事件的触发条件是输入框文本发生变更,你在回调逻辑中修改了textInput_.text属性,赋值操作会再次触发onValueChanged事件- 由此形成「文本变更→触发回调→修改文本→再触发回调」的死循环,最终栈空间耗尽抛出异常
解决方案
方案1:递归锁标志位(更稳妥)
新增布尔变量标记修改状态,回调触发时如果正在执行修改逻辑直接返回,避免递归:
using TMPro; using UnityEngine; public class TextChangeEvent : MonoBehaviour { public TMP_InputField textInput_; // 递归锁标志 private bool isUpdatingText = false; public void Start(){ textInput_.onValueChanged.AddListener(myTextChanged); } public void myTextChanged(string currentText){ // 正在修改文本时直接跳过 if (isUpdatingText) return; isUpdatingText = true; string newText = currentText.Replace("World", "Unity"); // 只有文本实际变更才赋值,减少不必要性能损耗 if (newText != currentText) { textInput_.text = newText; } isUpdatingText = false; } }
该方案无需反复增删事件监听,也避免了匿名委托无法正常移除的隐患,性能和稳定性更高。
方案2:修改文本前临时移除监听
修改文本前先把回调从监听列表移除,修改完成后再加回,避免赋值操作触发回调:
using TMPro; using UnityEngine; public class TextChangeEvent : MonoBehaviour { public TMP_InputField textInput_; private UnityAction<string> textChangeHandler; public void Start(){ textChangeHandler = myTextChanged; textInput_.onValueChanged.AddListener(textChangeHandler); } public void myTextChanged(string currentText){ textInput_.onValueChanged.RemoveListener(textChangeHandler); string newText = currentText.Replace("World", "Unity"); if (newText != currentText) { textInput_.text = newText; } textInput_.onValueChanged.AddListener(textChangeHandler); } }
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

