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

Unity Punnett方格游戏答题逻辑与状态重置问题求助

Unity Punnett方格游戏答题逻辑与状态重置问题求助

嘿,别担心!作为Unity新手遇到这种逻辑问题太正常了,我来帮你梳理和修复代码里的问题~

先说说你当前代码的核心问题:你在Update里同时检查所有四个槽的答案匹配,这就导致哪怕你在Slot1输入了Slot2的答案,代码也会误触发isCorrect2并跳转到Slot3。我们需要改成只检查当前正在作答的槽对应的正确答案,严格按顺序推进流程。

接下来分步骤解决你的三个需求:


一、修复严格按顺序答题的逻辑

我们可以用一个整数变量currentSlotIndex来跟踪当前要答的槽序号(1对应Slot1,2对应Slot2以此类推),这样就能精准控制答题流程:

  • 初始时currentSlotIndex设为1,默认作答Slot1
  • 只有当前槽的答案匹配对应正确值时,才推进到下一个槽
  • 把按钮监听从Update移到Start里(原代码重复添加监听会导致点击一次触发多次逻辑,是性能隐患)

二、单独跟踪当前槽的正确性

现在我们可以确保只有当前槽的答案会被校验,其他槽的isCorrectX不会被误触发。比如当currentSlotIndex=1时,只判断输入是否等于firstAnswer,只有匹配成功才把isCorrect1设为true,然后切换到Slot2。

三、添加状态重置功能

写一个ResetPunnettSquare()方法,用来一键重置所有状态:

  • 把所有isCorrectX和allCorrect设为false
  • 清空四个槽的文本内容
  • 把currentSlotIndex改回1,重新设置slotToAnswer为Slot1

修改后的完整代码

using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class AnswerScript : MonoBehaviour
{
    public bool isCorrect1, isCorrect2, isCorrect3, isCorrect4, allCorrect;
    public QuizManager quizManager;
    public GameObject slotToAnswer;
    public string firstAnswer, secondAnswer, thirdAnswer, fourthAnswer, currentInput;
    
    public TextMeshProUGUI dominantText, heteroText, recessiveText;
    public Button dominantButton, heteroButton, recessiveButton;

    // 跟踪当前要作答的槽序号(1-4)
    private int currentSlotIndex;

    void Start()
    {
        // 初始化按钮(建议直接在Inspector拖引用,比Find更高效)
        dominantButton = GameObject.Find("Dominant").GetComponent<Button>();
        heteroButton = GameObject.Find("Heterozygous").GetComponent<Button>();
        recessiveButton = GameObject.Find("Recessive").GetComponent<Button>();

        // 初始化文本
        dominantText = dominantButton.GetComponentInChildren<TextMeshProUGUI>();
        heteroText = heteroButton.GetComponentInChildren<TextMeshProUGUI>();
        recessiveText = recessiveButton.GetComponentInChildren<TextMeshProUGUI>();

        // 按钮监听只在Start里添加一次,避免重复绑定
        dominantButton.onClick.AddListener(TexttoDominant);
        heteroButton.onClick.AddListener(TexttoHetero);
        recessiveButton.onClick.AddListener(TexttoRecessive);

        // 初始化答题状态
        ResetPunnettSquare();
    }

    void Update()
    {
        // 先计算所有正确答案,统一处理aA转Aa的情况
        CalculateCorrectAnswers();

        // 只获取当前槽的输入文本
        currentInput = slotToAnswer.GetComponentInChildren<TextMeshProUGUI>().text;

        // 根据当前槽序号,只校验对应答案
        switch(currentSlotIndex)
        {
            case 1:
                CheckSlot1Answer();
                break;
            case 2:
                CheckSlot2Answer();
                break;
            case 3:
                CheckSlot3Answer();
                break;
            case 4:
                CheckSlot4Answer();
                break;
        }
    }

    // 计算所有正确答案,统一处理aA转Aa的情况
    private void CalculateCorrectAnswers()
    {
        firstAnswer = quizManager.allele1.text + quizManager.allele3.text;
        firstAnswer = NormalizeAlleleText(firstAnswer);

        secondAnswer = quizManager.allele2.text + quizManager.allele3.text;
        secondAnswer = NormalizeAlleleText(secondAnswer);

        thirdAnswer = quizManager.allele1.text + quizManager.allele4.text;
        thirdAnswer = NormalizeAlleleText(thirdAnswer);

        fourthAnswer = quizManager.allele2.text + quizManager.allele4.text;
        fourthAnswer = NormalizeAlleleText(fourthAnswer);
    }

    // 统一标准化等位基因文本(aA转Aa)
    private string NormalizeAlleleText(string text)
    {
        return text == "aA" ? "Aa" : text;
    }

    // 校验Slot1的答案
    private void CheckSlot1Answer()
    {
        if(currentInput == firstAnswer && !isCorrect1)
        {
            isCorrect1 = true;
            currentSlotIndex = 2;
            slotToAnswer = GameObject.Find("Slot2");
            Debug.Log("Slot1正确,现在作答Slot2");
        }
    }

    // 校验Slot2的答案
    private void CheckSlot2Answer()
    {
        if(currentInput == secondAnswer && !isCorrect2)
        {
            isCorrect2 = true;
            currentSlotIndex = 3;
            slotToAnswer = GameObject.Find("Slot3");
            Debug.Log("Slot2正确,现在作答Slot3");
        }
    }

    // 校验Slot3的答案
    private void CheckSlot3Answer()
    {
        if(currentInput == thirdAnswer && !isCorrect3)
        {
            isCorrect3 = true;
            currentSlotIndex = 4;
            slotToAnswer = GameObject.Find("Slot4");
            Debug.Log("Slot3正确,现在作答Slot4");
        }
    }

    // 校验Slot4的答案
    private void CheckSlot4Answer()
    {
        if(currentInput == fourthAnswer && !isCorrect4)
        {
            isCorrect4 = true;
            allCorrect = true;
            Debug.Log("恭喜!所有槽都答对了!");
            // 这里可以加延迟重置,或者等玩家点击重置按钮
            // Invoke("ResetPunnettSquare", 2f);
        }
    }

    // 按钮点击方法:设置当前槽为显性文本
    public void TexttoDominant()
    {
        slotToAnswer.GetComponentInChildren<TextMeshProUGUI>().text = dominantText.text;
    }

    // 按钮点击方法:设置当前槽为杂合文本
    public void TexttoHetero()
    {
        slotToAnswer.GetComponentInChildren<TextMeshProUGUI>().text = heteroText.text;
    }

    // 按钮点击方法:设置当前槽为隐性文本
    public void TexttoRecessive()
    {
        slotToAnswer.GetComponentInChildren<TextMeshProUGUI>().text = recessiveText.text;
    }

    // 重置整个Punnett方格的状态
    public void ResetPunnettSquare()
    {
        // 重置正确状态布尔值
        isCorrect1 = false;
        isCorrect2 = false;
        isCorrect3 = false;
        isCorrect4 = false;
        allCorrect = false;

        // 重置当前槽序号和目标槽
        currentSlotIndex = 1;
        slotToAnswer = GameObject.Find("Slot1");

        // 清空所有槽的文本
        GameObject.Find("Slot1").GetComponentInChildren<TextMeshProUGUI>().text = "";
        GameObject.Find("Slot2").GetComponentInChildren<TextMeshProUGUI>().text = "";
        GameObject.Find("Slot3").GetComponentInChildren<TextMeshProUGUI>().text = "";
        GameObject.Find("Slot4").GetComponentInChildren<TextMeshProUGUI>().text = "";

        Debug.Log("已重置Punnett方格,回到Slot1");
    }
}

关键修改点说明

  1. 添加currentSlotIndex变量:精准控制当前答题阶段,彻底避免跨槽误判
  2. 按钮监听只绑定一次:解决原代码重复绑定导致的多次触发问题
  3. 拆分校验逻辑:每个槽的校验独立,逻辑更清晰,也方便后续扩展
  4. 提取标准化方法:把aA转Aa的逻辑抽出来,减少重复代码
  5. 新增重置方法:一键回到初始状态,满足你的重置需求

使用小提示

  • 可以在UI里加一个重置按钮,把ResetPunnettSquare()方法绑定到按钮的OnClick事件上
  • 建议把四个Slot的引用直接拖到脚本的Inspector面板里,替换掉GameObject.Find(),这样更高效也更稳定
  • 当allCorrect为true时,你可以触发胜利动画、切换题目等自定义逻辑

备注:内容来源于stack exchange,提问作者f0rCE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:28:01