Issue on using GetKey(KeyCode.Keypad1) twice in the multiple if statements

I’m working on a small game in which I set 4 questions for players(students) to read and answer questions by pressing the keypad of NO. 1 and 2 on the keyboard.

When I used multiple If statements to enable and disable the questions to show up/turn off on the screen, I found the program always bypass the process which is enabled in the first press of the Keypad 1 and then disabled in the 2nd press of the same Keypad 1.

For example, I plan to let Question1 show up by pressing Keypad 1, and then Question1 turn off when players press the Keypad 1 again. In the meantime, the note to tell the player “Answer Correctly” is showed up.
If the player press the Keypad 2, the note to tell the player “Answer Incorrectly” is showed up.

The issue I faced is that the results always run “m_StartGame.SetActive (false)” and then bypass the process of “m_Question1.SetActive (true)”, and go to “m_CorrectNote.SetActive (true)” directly. May somebody help me to modify my script to fix this issue? Thanks a lot in advance.

Below is my C# script for this action:

bool Q1isActive=false;//means Question1 is not displayed on the screen.

// Update is called once per frame
void Update () {

if (Input.GetKey(KeyCode.Keypad0)) {
m_StartGame.SetActive (true);//statement of Start the Game is displayed.

}
if(Input.GetKey(KeyCode.Keypad1)){
m_StartGame.SetActive (false);
m_Question1.SetActive (true);//statement of Question1 is displayed.
Q1isActive = true;
}
if(Q1isActive==true&&Input.GetKey(KeyCode.Keypad1)){
m_Question1.SetActive (false);
m_CorrectNote.SetActive (true);//Statement of"Answer Correctly" is displayed.
}
if(Q1isActive==true&&Input.GetKey(KeyCode.Keypad2)){
m_Question1.SetActive (false);
m_WrongNote1.SetActive (true);//Statement of"Answer incorrectly" is displayed.
}

2733625–194324–keypad issue.txt (798 Bytes)

Use if and else if statements, otherwise your if statements are triggering after each other.

1 Like

Thank you, Brathnann. I will try to use the if and else if into my script, and check if results meet my plan.

I tried to use if and else if statements into my script, but found one issue. The program ran to the line 51 after hit the RedLightCollider. However, actually I want it to ran to the line 34.

How can I modify my script to reach this plan? Thanks for your kind advice in advance.
Below is my C# script:

using UnityEngine;
using System.Collections;

//[RequireComponent(typeof(AudioSource))]
public class NavigationMove : MonoBehaviour {
    [SerializeField]AudioSource m_start, m_correct, m_wrong;
    [SerializeField] GameObject m_GameRule, m_GameOver1, m_GameOver2, m_GameOver3, m_PressKeyNote, m_WrongButton, m_StartGame, m_Question1, m_CorrectNote, m_WrongNote1, m_Question2,m_TurnLeftNote, m_WrongNote2,
    m_ReplayNote, m_Question3, m_Question4, m_EndFirstStage, m_HospitalArrive, m_SecondStageQuestion, m_Question5, m_Question6, m_Question7, m_TurnRightNote, m_ScoreNote, m_GameOver4;
    NavMeshAgent agent;
    GameObject m_hospital;
    Rigidbody m_Rigidbody;

    // Use this for initialization
    void Start () {
        agent = GetComponent<NavMeshAgent> (); 
        m_hospital = GameObject.FindWithTag ("Hospital");
        m_Rigidbody = GetComponent<Rigidbody> ();
        m_start=GetComponent<AudioSource>();
        m_start.Play ();
    }

    bool startisActive=false;//means m_StartGame.SetActive(false);
 
    // Update is called once per frame
    void Update () {
        agent.destination = m_hospital.transform.position;
        if (Input.GetKey (KeyCode.Keypad0)) {
            m_GameRule.SetActive (false);
            m_start.Play ();
            agent.destination = m_hospital.transform.position;
            agent.speed = 20;
            startisActive = false;

            if (startisActive == true)
            if (Input.GetKey (KeyCode.Keypad1)) {
                m_StartGame.SetActive (false);
                m_Question1.SetActive (true);
            } else if (Input.GetKey (KeyCode.Keypad0) || Input.GetKey (KeyCode.Keypad2) || Input.GetKey (KeyCode.Keypad3) ||
                        Input.GetKey (KeyCode.Keypad4) || Input.GetKey (KeyCode.Keypad5) || Input.GetKey (KeyCode.Keypad6) ||
                        Input.GetKey (KeyCode.Keypad7) || Input.GetKey (KeyCode.Keypad8) || Input.GetKey (KeyCode.Keypad9)) {
                if (Input.GetKey (KeyCode.Keypad1)) {
                    m_StartGame.SetActive (false);
                    m_Question1.SetActive (true);
                } else if (Time.time > 15f) {
                    m_StartGame.SetActive (false);
                    m_GameOver2.SetActive (true);
                }
         
            }

        } else if (Input.GetKey (KeyCode.Keypad1) || Input.GetKey (KeyCode.Keypad2) || Input.GetKey (KeyCode.Keypad3) ||
                   Input.GetKey (KeyCode.Keypad4) || Input.GetKey (KeyCode.Keypad5) || Input.GetKey (KeyCode.Keypad6) ||
                   Input.GetKey (KeyCode.Keypad7) || Input.GetKey (KeyCode.Keypad8) || Input.GetKey (KeyCode.Keypad9))
        {
            if (Input.GetKey (KeyCode.Keypad0)) {
                m_start.Play ();
                agent.destination = m_hospital.transform.position;
                agent.speed = 20;
            } else if (Time.time > 15f)
            {
                m_GameRule.SetActive (false); 
                m_GameOver1.SetActive (true);
            }
        }
    }


        void OnTriggerEnter(Collider other){
            if(other.gameObject.layer==LayerMask.NameToLayer("Collider")){
                m_start.Pause ();
                agent.speed=0;
            }
            if (other.tag=="RuleCollider"){
                m_GameRule.SetActive(true);
            }
            if (other.tag == "RedLightCollider") {
                m_GameRule.SetActive (false);
                m_StartGame.SetActive (true);
                startisActive = true;
            }
         
    }
}

Not sure what you mean. When you hit your redlightcollider, you’re setting startisactive to true. Which means if you hit key0, it’s going to enter the input keycode.keypad0. Your next if is for keypad1, but that isn’t going to run because you hit keypad0, so the else if runs.

The process to hit the keypad is:

  1. press the keypad0 to start move forward when I hit the RuleCollider. If I press any of the number key except the keypad0, and the time is over 15seconds, the GameOver1 notice will show up to end the game. If I finally hit the keypad0 within 15seconds, I still can move forward.
  2. Next step is to hit the RedLightCollider when I keep moving forward. The m_StartGame show up to ask me to press keypad1 to enter the question section which is planned to put after line43.

The program failed in the process 2 as it didn’t run to the section after line34. In order to let program run into the line34 (not go to line 51 which has the same choice to get hit of keypad1) when I press keypad1, so I add one var(startisActive) to control the program to run the line 34 if I press the keypad1 (which is pressed after the keypad0 when I passed the RuleCollider). The bool (startisActive==true) I put on line 79 is to tell the program that it should run into the line 34, not line 51, as the bool status of line51 should keep default as false.

However, the results always bypass the line 34~49, and go to line 51~64 even I press the keypad1 (at this moment, I didn’t hit keypad0). I tried to add the curly brackets after if(startisActive) but still failed to enter the line 34.

Hope this clarify my idea on the game operation and get your feedback to modify my code.
Thanks a lot again.

Ah, overlooked something myself. StartIsActive is never going to be true. If I’m holding down keypad0, you’re constantly setting it back to false. Even if I enter the trigger which sets it to true, it will be set back to false in update pretty much right away since I’m holding down keypad0.

I’m still not sure what you are trying to do 100%. Your code is very confusing, but I tried to modify it for you. I commented out a bunch of stuff because I wasn’t sure what was going on or should happen.

This is untested, say it might not be perfect, and in some cases I feel this could be done a lot better.

using UnityEngine;
using System.Collections;

//[RequireComponent(typeof(AudioSource))]
public class NavigationMove : MonoBehaviour
{
    [SerializeField]
    AudioSource m_start, m_correct, m_wrong;
    [SerializeField]
    GameObject m_GameRule, m_GameOver1, m_GameOver2, m_GameOver3, m_PressKeyNote, m_WrongButton, m_StartGame, m_Question1, m_CorrectNote, m_WrongNote1, m_Question2, m_TurnLeftNote, m_WrongNote2,
    m_ReplayNote, m_Question3, m_Question4, m_EndFirstStage, m_HospitalArrive, m_SecondStageQuestion, m_Question5, m_Question6, m_Question7, m_TurnRightNote, m_ScoreNote, m_GameOver4;
    NavMeshAgent agent;
    GameObject m_hospital;
    Rigidbody m_Rigidbody;

    // Use this for initialization
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        m_hospital = GameObject.FindWithTag("Hospital");
        m_Rigidbody = GetComponent<Rigidbody>();
        m_start = GetComponent<AudioSource>();
        m_start.Play();
    }

    bool startisActive = false;//means m_StartGame.SetActive(false);
    bool rulesAreActive = false;

    // Update is called once per frame
    void Update()
    {
        agent.destination = m_hospital.transform.position;
        if (Input.GetKey(KeyCode.Keypad0) && !startisActive) //This will move you forward till you hit the trigger. Requires holding down the key.
        {
            m_GameRule.SetActive(false);
            m_start.Play();
            agent.destination = m_hospital.transform.position;
            agent.speed = 20;
        }

        if(rulesAreActive) //After trigger rules, this checks if you hit any key other than 0 and then checks the time.
        {
            if (Input.GetKeyDown(KeyCode.Keypad1) || Input.GetKeyDown(KeyCode.Keypad2) || Input.GetKeyDown(KeyCode.Keypad3) ||
                     Input.GetKeyDown(KeyCode.Keypad4) || Input.GetKeyDown(KeyCode.Keypad5) || Input.GetKeyDown(KeyCode.Keypad6) ||
                     Input.GetKeyDown(KeyCode.Keypad7) || Input.GetKeyDown(KeyCode.Keypad8) || Input.GetKeyDown(KeyCode.Keypad9))
            {
                if (Time.time > 15f)
                {
                    m_StartGame.SetActive(false);
                    m_GameOver2.SetActive(true);
                }
            }
        }

        if (startisActive) //You've now activated the redlightcollider trigger and will no longer move forward.
        {
            if ((Input.GetKeyDown(KeyCode.Keypad1))) //Player hits 1
            {
                m_StartGame.SetActive(false);
                m_Question1.SetActive(true);
            }
            else if (Input.GetKeyDown(KeyCode.Keypad0) || Input.GetKeyDown(KeyCode.Keypad2) || Input.GetKeyDown(KeyCode.Keypad3) ||
                     Input.GetKeyDown(KeyCode.Keypad4) || Input.GetKeyDown(KeyCode.Keypad5) || Input.GetKeyDown(KeyCode.Keypad6) ||
                     Input.GetKeyDown(KeyCode.Keypad7) || Input.GetKeyDown(KeyCode.Keypad8) || Input.GetKeyDown(KeyCode.Keypad9)) //Player hits another key than 1
            {
                //**********Something should happen here? Not sure if game is suppose to be over again or what happens?
                //if (Input.GetKey(KeyCode.Keypad1))
                //{
                //    m_StartGame.SetActive(false);
                //    m_Question1.SetActive(true);
                //}
                //else if (Time.time > 15f)
                //{
                //    m_StartGame.SetActive(false);
                //    m_GameOver2.SetActive(true);
                //}

            }
        }
        //*********Not sure what this is suppose to do...
        //else if (Input.GetKey(KeyCode.Keypad1) || Input.GetKey(KeyCode.Keypad2) || Input.GetKey(KeyCode.Keypad3) ||
        //         Input.GetKey(KeyCode.Keypad4) || Input.GetKey(KeyCode.Keypad5) || Input.GetKey(KeyCode.Keypad6) ||
        //         Input.GetKey(KeyCode.Keypad7) || Input.GetKey(KeyCode.Keypad8) || Input.GetKey(KeyCode.Keypad9))
        //{
        //    if (Input.GetKey(KeyCode.Keypad0))
        //    {
        //        m_start.Play();
        //        agent.destination = m_hospital.transform.position;
        //        agent.speed = 20;
        //    }
        //    else if (Time.time > 15f)
        //    {
        //        m_GameRule.SetActive(false);
        //        m_GameOver1.SetActive(true);
        //    }
        //}
    }


    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.layer == LayerMask.NameToLayer("Collider"))
        {
            m_start.Pause();
            agent.speed = 0;
        }
        if (other.tag == "RuleCollider")
        {
            m_GameRule.SetActive(true);
            rulesAreActive = true;
        }
        if (other.tag == "RedLightCollider")
        {
            m_GameRule.SetActive(false);
            m_StartGame.SetActive(true);
            startisActive = true;
            rulesAreActive = false;
        }

    }
}

Thanks for your prompt response. It seems that I need to trim my code in some parts which are confusing. Before I do it, I would like to check one point.

I set the startisActive become true after I hit the RedLightCollider. This is supposedly not to be set back to false because the questions are going to be answered by pressing keypad1 or keypad2 (no keypad0). Only if the player hit a wrong keypad0, then startisActive will become false. This means the game should be over because the player don’t press the correct keypad within the timeduration I set.