Input.KeyDown not reacting in OnTriggerStay2D :( help needed

Hello everybody,

I just ran into a problem.
I have a Player and a sign. The player can approach the sign and read it.

The sign has two BoxCollider2D …one of em is “solid” (Is Trigger = false) and the other one is a trigger.
The one that is a trigger is the area that the player must touch to beeing able to read the sign.

Here is a screenshot

The collision is detected perfectly… and this is the script I use within the objSign

using UnityEngine;
using System.Collections;

public class Sign : MonoBehaviour
{
    [Multiline]
    public string textToDisplay = "";

    public GameObject textBox;

    private bool isReading = false;
   
    void OnTriggerStay2D(Collider2D coll)
    {
        if (this.isReading)
            return;

        if (coll.gameObject.tag == "Player")
        {
            Debug.Log("contact");
            if (Input.GetKeyDown(KeyCode.F))
            {
                UnityEngine.UI.Text text = (UnityEngine.UI.Text) textBox.transform.Find("Text").GetComponent(typeof(UnityEngine.UI.Text));

                if (text)
                    Debug.Log("found");
                else
                    Debug.Log("not");

                this.isReading = true;
                this.textBox.SetActive(true);

                text.text = this.textToDisplay;
            }
        }
    }
}

The wierd thing is, the collision is detected correctly…but the Input.GetKeyDown only reacts very rarely. I have to mash the button a lot to finally get it running. Is there anythign I missed?

Thanks in advance :slight_smile:

FixedInput (and therefore OnTriggerStay2D) runs at the physics framerate, which does not necessarily match the actual framerate. All one-time events such as Down and Up are only true for that single frame. So all input like that must be checked in Update.

–Eric

1 Like

Okay…but…then…wait…

So, the OnTriggerStay2D is not in the “fixed” pipe?
How should I then approach this?

Would I perform the button check first and then check if there is the player in the collision box? :frowning:

Edit
Can you please try to explain the following:

I changed the OnTriggerStay2D to this

void OnTriggerStay2D(Collider2D other)
    {
        if (this.isReading)
            return;

        this.hasPlayerContactThisFrame = (other.gameObject.tag == "Player");

        Debug.Log (this.hasPlayerContactThisFrame);
    }

and, now in the game I move into the collision box and from there on I do NOT move.
The Console shows this

False
UnityEndinge.Debug:Log(Object)
True
UnityEndinge.Debug:Log(Object)
False
UnityEndinge.Debug:Log(Object)
False
UnityEndinge.Debug:Log(Object)
True
UnityEndinge.Debug:Log(Object)
...
...

The list keeps going on and on…how come sometimes the collision isn’t detected? :S

Edit
Okay…no idea why, but the sign has contact with something else besides the player as soon as the player moves towards the sign close enough…could it be…the camera? …I think I am approaching the whole thing the wrong way.

Edit
It turned out the objSign had a collision with itself…but only when the player approached the sign…no idea how this can happen…anyway, I still couldn’t solve the problem on how to correctly detect collision AND KeyDown in the same frame :frowning:

It is, which is the problem. FixedUpdate generally runs less often than Update and can miss input.

Use OnTrigger to signal whether the object is in a trigger and check input accordingly in Update.

–Eric

1 Like

Thank you for your reply.
I now changed it to this

using UnityEngine;
using System.Collections;

public class Sign : MonoBehaviour
{
    [Multiline]
    public string textToDisplay = "";

    public GameObject textBox;

    private bool isReading = false;
    private bool hasPlayerContactThisFrame;

    void OnTriggerStay2D(Collider2D other)
    {
        if (this.isReading)
            return;

        this.hasPlayerContactThisFrame = (other.gameObject.tag == "Player");
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.tag == "Player")
            this.hasPlayerContactThisFrame = false;
    }

    void reactivatePlayer()
    {
        this.textBox.SetActive(false);
        GameController.singleton.player.enableMovement();

        this.isReading = false;
    }

    void Update()
    {
        if (this.hasPlayerContactThisFrame)
        {
            if (Input.GetKeyDown(KeyCode.F))
            {
                GameController.singleton.player.disableMovement();
               
                UnityEngine.UI.Text text = (UnityEngine.UI.Text) textBox.transform.Find("Text").GetComponent(typeof(UnityEngine.UI.Text));

                this.isReading = true;
                this.textBox.SetActive(true);
               
                text.text = this.textToDisplay;
               
                Invoke ("reactivatePlayer", 2.0f);
            }
        }
    }
}

It basicly works…but when a GameObject other than the Player object touches the collider it will not work anymore.
I think I am still missing something here.

Once again, thank you for your help