NovaBlade
NovaBlade

Reputation: 25

InputGetKeyDown in OnTriggerStay is called multiple times

I have a game where if an invisible box is touching an object and press "e", text will display depending on what object is touched. The problem is somethimes (it's kinda random) it will run the text three times. I've tried putting the inputkey in update, I've tried some Booleans to test if it's been run more than once, I've checked if there's more than one script doing this, but nothing works.

private void OnTriggerStay(Collider other)
{
    if (Input.GetKeyDown(name: "e") && other.tag == "Mar Room")
    {
        switch (other.gameObject.name)
        {
            case "Cushion1":

                other.transform.rotation = Quaternion.Euler(-90, 0, 0);
                other.transform.localPosition = new Vector3(-206.849f, 108.2456f, -48.99983f);
                runSentence("CouchText");
                Debug.Log("I have been called cush");
                items += 1;
                break;
            case "Chair":
                other.transform.rotation = Quaternion.Euler(-90, 0, 90);
                other.transform.localPosition = new Vector3(-182.399f, 108.6756f, -16.16f);
                runSentence("ChairText");
                Debug.Log("I have been called chair");
                items += 1;
                break;
            case "Lamp":
                other.transform.rotation = Quaternion.Euler(-90, 0, 0);
                other.transform.localPosition = new Vector3(-180.779f, 111.3156f, -47.82983f);
                runSentence("LampText");
                items += 1;
                Debug.Log("I have been called lamp");
                break;
            case "Time":
                other.transform.rotation = Quaternion.Euler(0, 90, 0);
                other.transform.localPosition = new Vector3(-178.499f, 110.5756f, -37.59983f);
                runSentence("HourglassText");
                items += 1;
                Debug.Log("I have been called time");
                break;
            case "Art":
                other.transform.rotation = Quaternion.Euler(0, 0, 0);
                other.transform.localPosition = new Vector3(-190.499f, 113.3056f, -51.31983f);
                runSentence("PictureText");
                items += 1;
                Debug.Log("I have been called art");
                break;

            default:
                break;
        }
    }
}

Upvotes: 2

Views: 853

Answers (2)

Never do input processing in a Physics function

Physics functions run at set intervals while keyboard input runs on renderframe intervals (which are irregular and may be either longer or shorter than Physics steps, causing duplicated or dropped inputs).

You need to instead hold a reference from the physics operation over into the standard Update() loop where you check for keypresses and do your actions there:

private GameObject nearTo = null

private void OnTriggerStay(Collider other) {
    if (other.tag == "Mar Room") {
        nearTo = other.gameObject;
    }
}

private void Update() {
    if(nearTo != null && Input.GetKeyDown(name: "e")) {
        //do stuff
        nearTo = null; //set to null when we're done
    }
}

Also, I don't think Input.GetKeyDown(name: "e") is valid code, but that might have been edited for our convenience rather than actual implementation.

Upvotes: 3

Andy Smith
Andy Smith

Reputation: 11

You might be having an issue where on trigger stay can be called multiple times if you are maybe interacting with multiple triggers. GetKeyDown remains true for the entire frame that it is being looked at, so if you have set your physics tick to be at a higher rate than the frame rate you will also be getting multiple calls.

Upvotes: 1

Related Questions