VedPurohit
VedPurohit

Reputation: 1

How can I input and destroy the other gameObject on Trigger

I want to destroy a GameObject when it hits the trigger but with an input. No errors, but its not working in unity

using UnityEngine;

public class DestroyTile : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Tile"))
        {
            if(Input.GetKeyDown(KeyCode.Space))
            {
                Destroy(other.gameObject);
            }
        }
    }
}

what should I do to make this work??

Upvotes: 0

Views: 2285

Answers (1)

derHugo
derHugo

Reputation: 90872

Very unlikely that you manage to hit the key in exactly the same frame the collision happens ;)

As a quick fix rather use OnTriggerStay

OnTriggerStay is called once per physics update for every Collider other that is touching the trigger.

public class DestroyTile : MonoBehaviour
{
    // Called once every FixedUpdate for each trigger you are touching
    private void OnTriggerStay(Collider other)
    {
        if (other.CompareTag("Tile"))
        {
            if(Input.GetKeyDown(KeyCode.Space))
            {
                Destroy(other.gameObject);
            }
        }
    }
}

With above way there is only one last issue: OnTriggerStay is not actually called every frame but rather every FixedUpdate so you might miss a key press if it happened in a frame where FixedUpdate isn't called. Therefore in general getting User input within FixedUpdate (or other physics based continuous methods) is unreliable and should always be done in Update.

So instead you could/should do something like e.g.

public class DestroyTile : MonoBehaviour
{
    private readonly HashSet<GameObject> _currentlyTouching = new HashSet<GameObject>();

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Tile") return;

        // For some reason we still have the other object stored
        if(_currentlyTouching .Contains(other.gameObject)) return;
       
        // Store the other object
        _currentlyTouching.Add(other.gameObject);
    }
    
    private void OnTriggerExit(Collider other)
    {
        // We don't have this other object stored
        if(!_currentlyTouching.Contains(other.gameObject) return;
        
        // remove this other object
        _currentlyTouching.Remove(other.gameObject);
    }
    
    private void Update()
    {
        // Are we touching anything?
        // This check is cheaper than Input.GetKeyDown
        if(_currentlyTouching.Count <= 0) return;

        if(!Input.GetKeyDown(KeyCode.Space)) return;
        
        // destroy (all) the touched object(s)
        foreach(var obj in _currentlyTouching)
        {
            Destroy(obj);
        }

        // Don't forget to also clear the HashSet in that case
        _currentlyTouching.Clear();
    }
}

This way you have the User Input separated in Update (every frame) and only track the entering and exiting colliders via the Physcis based system.

Upvotes: 1

Related Questions