OnTriggerEnter2D - How do I use this?

Hi
I’m making a shop system and I would like to be able to press E to enter the shop. I have made an invisible game object that is now a Trigger, where the shop should be accesible. Only problem is that I cant get it to work.

void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == “Player”)
{
if(Input.GetKeyDown(KeyCode.E))
{
Debug.Log(“I pressed E”);
}
}
}

When instantaneous Input methods (GetKeyDown, GetMouseButtonDown, and others) are used in FixedUpdate or any physics message function (OnCollisionEnter for example) they will be triggered inconsistently.

Why?

FixedUpdate and physics message functions are run at a fixed rate, sometimes multiple times a frame, and are frame-rate independent. If input occurs on a frame where FixedUpdate or a message function isn’t run, it won’t be processed by your code.
See FixedUpdate for more information.


When using physics callbacks and not calling physics functions, you can move your logic to Update.

Example

private bool _inTrigger;

void Update()
{
    // Not in trigger, don't run code below
    if (!_inTrigger) return;

    if (Input.GetKeyDown(KeyCode.E))
        Example();
}

void OnTriggerEnter(Collider other)
{
    if (!other.gameObject.CompareTag("Player"))
        return;
    _inTrigger = true;
}

void OnTriggerExit(Collider other)
{
    if (!other.gameObject.CompareTag("Player"))
        return;
    _inTrigger = false;
}

If you expect overlapping triggers, this logic should involve a counter.


Note that you should also be using CompareTag, not string equality to compare tags. It doesn’t allocate garbage and it also provides warnings for incorrect tags.

OnTriggerEnter only gets called the first frame when two objects “collide”. OnTriggerStay gets called every frame after that, until they separate.

void OnTriggerStay2D(Collider2D other)
{
    if(other.gameObject.tag == “Player”)
    {
        if(Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("I pressed E");
        }
    }
}

You could try combining OnTriggerEnter and OnTriggerExit:

public bool isInsideShop = false;
void OnTriggerEnter2D(Collider2D other)
{
    if(other.gameObject.tag == “Player”)
    {
        isInsideShop = true;
    }
}

void OnTriggerExit2D(Collider2D other)
{
    if(other.gameObject.tag == “Player”)
    {
        isInsideShop = false;
    }
}

void Update()
{
    if(isInsideShop && Input.GetKeyDown(KeyCode.E))
    {
        Debug.Log("I pressed E while inside shop");
    }
}

With this approach you should also be able to see if the game thinks that you are inside the shop, by looking at the bool