Unity字符串比较失效:按钮文本为...却未触发禁用逻辑
问题排查与解决方法
核心问题分析
你的代码逻辑存在时序混乱和跨索引UI修改的问题,这是导致偶发失效的根本原因:
- 循环中先给当前索引
b的按钮文本赋值,随后又可能修改其他索引的按钮文本,但这些被修改的按钮,要等到循环到对应索引时才会处理可交互状态;而轮到它们的循环时,又会先执行buttonText.text = stage.getPlayerActions(b),覆盖之前的"..."文本,导致判断逻辑出错。 - 字符串比较未考虑TMP文本可能存在的隐藏字符(如首尾空格、换行)或潜在的富文本标记。
具体修复方案
1. 重构逻辑:先计算所有按钮的最终文本,再统一设置UI状态
避免循环内跨索引修改UI,先批量确定每个按钮的最终显示内容,再一次性设置文本和可交互状态,彻底解决时序问题:
void DisplayTextBody(Stage nextStagePara) { textToWrite.text = stage.getTextBody(); int length = stage.getPlayerActionLength(); // 第一步:提前计算所有按钮的最终文本 string[] buttonTexts = new string[length]; for(int b = 0; b < length; b++) { buttonTexts[b] = stage.getPlayerActions(b); } // 应用特殊文本替换逻辑,同时做索引合法性检查 if (!saveScript.game_Data.getInventory().Contains("MindRune") && stage.getMindRuneStage() != null) { int mindIndex = stage.getMindRuneIndex(); if(mindIndex >= 0 && mindIndex < length) buttonTexts[mindIndex] = "..."; } if(!saveScript.game_Data.getInventory().Contains("BodyRune") && stage.getBodyRuneStage() != null) { int bodyIndex = stage.getBodyRuneIndex(); if(bodyIndex >= 0 && bodyIndex < length) buttonTexts[bodyIndex] = "..."; } if(!saveScript.game_Data.getInventory().Contains(stage.getRequiredItem()) && stage.getRequiredItemStage() != null) { int itemIndex = stage.getItemIndex(); if(itemIndex >= 0 && itemIndex < length) buttonTexts[itemIndex] = "..."; } // 第二步:统一设置文本和可交互状态 for(int b = 0; b < length; b++) { TextMeshProUGUI buttonText = responseButtons[b].GetComponentInChildren<TextMeshProUGUI>(); Button button = responseButtons[b].GetComponent<Button>(); buttonText.text = buttonTexts[b]; // 严谨的字符串比较,去除首尾空白避免隐藏字符干扰 bool shouldDisable = buttonTexts[b].Trim().Equals("..."); button.interactable = !shouldDisable; Debug.Log($"按钮{b}:文本={buttonTexts[b]},可交互={button.interactable}"); } }
2. 额外排查点
- 检查其他代码是否覆盖状态:确认没有在按钮点击事件、
Update或其他生命周期方法中修改按钮的interactable属性,导致这里的设置被覆盖。 - TMP文本的富文本检查:如果
stage.getPlayerActions(b)返回的是带富文本标记的内容,即使显示是"...",实际text值可能包含标签,此时可以用buttonTexts[b].Contains("...")替代严格相等判断,或确保数据源返回纯文本。
内容的提问来源于stack exchange,提问作者Seldkam
相关产品推荐
相关产品推荐

