Unity3D Input.GetKeyDown and OnTriggerEnter problem

This is my first time submitting a problem here. It’s in first person. The problem I’m having, is that when the player enters the box collider and presses E the text with E show up but then when I click E it sometimes switch the lights and sometimes not. I have one scripts, LightOnOff, which is attached to the component with the light and with the box collider(trigger). I can’t seem to figure out a solution to this problem and any help would be much appreciated. Here is the script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LightOnOff : MonoBehaviour
{
    public GameObject intText;
    Light myLight;

    public KeyCode interactionKey = KeyCode.E;
    

    void Start()
    {
        myLight = GetComponent<Light>();
    }    

    void OnTriggerStay(Collider other)
    {
        if(other.CompareTag("MainCamera"))
        {
            intText.SetActive(true);

            if(Input.GetKeyDown(interactionKey))
            {
                myLight.enabled = !myLight.enabled;
            }            
        }
    }

    void OnTriggerExit(Collider other)
    {
        if(other.CompareTag("MainCamera"))
        {
            intText.SetActive(false);
        }
    }
}

Hi.

Do your Input.GetKeyDown(interactionKey) check in Update instead of OnTriggerStay.

Use OnTriggerEnter and Exit.

In enter store a state in field like “playerClose” if player is close.

Then in update, if player presses interaction key, check that playerIsClose is true, and only then toggle light either on or off.

public class LightOnOff : MonoBehaviour
{
    [SerializeField] GameObject myText;
    [SerializeField] Light myLight;
    [SerializeField] KeyCode interactionKey = KeyCode.E;
    [SerializeField] bool playerIsClose;

    private void Start() => myLight = GetComponent<Light>();

    private void Update()
    {
        if (Input.GetKeyDown(interactionKey) && playerIsClose)
        {
            myLight.enabled = !myLight.enabled;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("MainCamera"))
        {
            myText.SetActive(true);
            playerIsClose = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("MainCamera"))
        {
            myText.SetActive(false);
            playerIsClose = false;
        }
    }
}
  1. First of all Input.GetKeyDown() should be checked inside Update() method.
  2. In update you will perform the input check and there you only need to know if player is inside or outside.
  3. That means you need some sort of flag, boolean will do the job for now.
  4. Instead of OnTriggerStay, have only OnTriggerEnter and OnTriggerExit, in there you set the boolean isInside true or false.
  5. In update after get key down just add additional check if(isInside) and then perform your action.