Unity基于玩家回答的问答系统故障排查与优化求助
故障分析与解决
核心问题定位
- 索引逻辑错误:选择"是"/"否"后,
positiveIndex/negativeIndex已递增,但typeLine方法始终用固定的index读取分支数组,导致后续无法切换到下一个问题。 - 状态未重置:
hasAnswered设为true后从未重置,后续逻辑判断会一直走分支流程,状态逻辑混乱。 - 无输入锁定:打字动画过程中仍能触发按键,导致多次触发分支切换,打断正常流程。
- 未处理数组越界:没有判断索引是否超出数组长度,容易引发空引用或索引越界报错。
修复步骤
- 修正索引引用:读取分支文本时,使用对应的
positiveIndex/negativeIndex替代固定的index。 - 重置状态标记:每次开始打字前重置
hasAnswered,避免状态残留。 - 添加输入锁定:新增
isTyping变量,打字过程中禁止响应按键输入。 - 处理数组越界:在切换分支前判断索引是否超出数组范围,超出则触发结束逻辑。
- 规范命名:遵循C#大驼峰命名规范,提升代码可读性。
优化后的完整代码
using UnityEngine; using TMPro; using System.Collections; public class QuestionScript : MonoBehaviour { [Header("UI组件")] public TextMeshPro questionText; public TextMeshPro positiveText; public TextMeshPro negativeText; public TextMeshProUGUI positiveTextIndex; public TextMeshProUGUI negativeTextIndex; [Header("问答文本")] public string[] initialLines; public string[] positiveLines; public string[] negativeLines; [Header("打字速度")] public float textSpeed = 0.1f; private bool hasAnswered = false; private bool isTyping = false; private bool positiveAnswer; private int initialIndex; private int positiveIndex; private int negativeIndex; private void Start() { questionText.text = string.Empty; StartDialogue(); } private void Update() { if (!isTyping) { CheckAnswer(); } UpdateIndexUI(); CheckEndCondition(); } private void StartDialogue() { initialIndex = 0; StartCoroutine(TypeLine()); } private IEnumerator TypeLine() { isTyping = true; questionText.text = string.Empty; char[] targetChars; if (hasAnswered) { targetChars = positiveAnswer ? positiveLines[positiveIndex].ToCharArray() : negativeLines[negativeIndex].ToCharArray(); } else { targetChars = initialLines[initialIndex].ToCharArray(); } foreach (char c in targetChars) { questionText.text += c; yield return new WaitForSeconds(textSpeed); } isTyping = false; } private void CheckAnswer() { if (Input.GetKeyDown(KeyCode.E)) { positiveAnswer = true; ChooseNextLine(); } else if (Input.GetKeyDown(KeyCode.R)) { positiveAnswer = false; ChooseNextLine(); } } private void ChooseNextLine() { hasAnswered = true; if (positiveAnswer) { if (positiveIndex >= positiveLines.Length - 1) { EndGame(); return; } positiveIndex++; } else { if (negativeIndex >= negativeLines.Length - 1) { EndGame(); return; } negativeIndex++; } StartCoroutine(TypeLine()); } private void UpdateIndexUI() { positiveTextIndex.text = positiveIndex.ToString(); negativeTextIndex.text = negativeIndex.ToString(); } private void CheckEndCondition() { if (positiveText.text == "fine" || negativeText.text == "fine") { Destroy(questionText); } } private void EndGame() { Debug.Log("问答流程结束"); isTyping = true; } }
额外优化建议
- 将问答数据封装为
Question类,包含问题文本、分支索引,实现更灵活的树状分支逻辑。 - 把按键绑定改为可配置的输入轴,方便后续修改操作方式。
- 添加打字音效与文本淡入效果,提升玩家体验。
- 替换
Destroy(questionText)为更优雅的UI隐藏逻辑,避免销毁组件后无法复用。
内容的提问来源于stack exchange,提问作者Leonardo Biagi
相关产品推荐
相关产品推荐

