Is Destroy(transform.parent.gameObject) Unreliable?

Good day. On my first project here.

Im trying have it so when the Player gets in range of the “Powerup” GameObject, a UI text will tell them to “press ‘E’” to pick up. When they do so their JumpHeight is affected and the Powerup Object & text are destroyed.

However I found that eventhough the JumpHeight stats are always changed, the GameObject & UI aren’t destroyed every time, usually requiring to press ‘E’ 2 to 4 times for it to work. I can’t seem to figure out what the issue is.

This is split on two scripts:

Script below is the first one, set to the Collider around the “Powerup” GameObject, Parent of said Collider

public class JumpAlert : MonoBehaviour
{
    public GameObject uiText;
    void Start()
    {
        uiText.SetActive(false);
    }
    public void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            uiText.SetActive(true);
            
        }
        
    }
    public void OnTriggerStay(Collider other)
    {

        if (other.gameObject.tag == "Player" && Input.GetKeyDown("e"))
        {
            uiThing.SetActive(false);
            Destroy(transform.parent.gameObject);
        }

    }
       public void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            uiThing.SetActive(false);
        }
    }
   
}

Script below are the relevant parts of the second script, set to the Player Controller.

public Transform powerCheck;
public float powerCheckArea = 1f;
public LayerMask powerCheckMask;

-

 nearpowerup = Physics.CheckSphere(powerCheck.position, powerCheckArea, powerCheckMask);


        if(nearpowerup && Input.GetKeyDown("e"))
        {
            jumpHeight = 100f;
            gravity = -7;
            Debug.Log("POWERS AQUIRED");


        }

As you can see the same If statement Input requirement is set in both scripts, which I could asume creates problems when two scripts are trying to use at the same time? You probably can tell im a total beginner.

To note is that if i change Destroy(transform.parent.gameObject) to Destroy(gameObject) to kill the Collider itself, it works fine, hence the title question.

Not sure how relevant this might be, but it seems to work if I enter the Collider, exit it, and then enter it again.

Thank you.

According to the documentation, OnTriggerStay isn’t guaranteed to run every frame. I’m assuming that’s the reason your key presses aren’t always being registered.

There are a few different ways you can solve this. One of the easiest is to use a boolean variable that’s set to True in OnTriggerEnter and False in OnTriggerExit (or vice versa). You can then handle your input inside Update (which is guaranteed to run every frame) and react differently according to whether the boolean is True or False. As for OnTriggerStay, you can just ditch it completely.

Here’s some revised code you can try out:

 public class JumpAlert : MonoBehaviour
 {
      public GameObject uiText;
      bool playerIsColliding = false;
      
      void Start()
      {
          uiText.SetActive(false);
      }
      
      void Update()
      {
          if (Input.GetKeyDown("e") && playerIsColliding)
          {
              Destroy(transform.parent.gameObject);
          }
      }
      
      void OnTriggerEnter(Collider other)
      {
          if (other.gameObject.tag == "Player")
          {
              uiText.SetActive(true);
              playerIsColliding = true;
          }
      }
      
      void OnTriggerExit(Collider other)
      {
          if (other.gameObject.tag == "Player")
          {
              uiThing.SetActive(false);
              playerIsColliding = false;
          }
      }
 }