You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:36:03