GameObject not colliding properly with a collider!

Hi! So I’ve got a gameObject that’s colliding with a box collider! When this happens there is a canvas that’s activating a text! Everything is okay till the moment when the two objects have to collide with each other… When the gameObject collide with the box collider the text I want to appear is doing it but only for a moment… Here is what I mean Gif > uEU_M5 is an Animated GIF Image on Make a GIF

and this is my code for the gameObject

       public Text text;
        public GameObject panel;
   
        void Start()
        {
            text = GameObject.Find("sewingCanvas/GameObject/Panel/Text").GetComponent<Text>();
            panel = GameObject.Find("sewingCanvas/GameObject/Panel");
            panel.SetActive(false);
            text.gameObject.SetActive(false);
        }
   
        void OnTriggerEnter(Collider co)
        {
                if (co.tag == "archieoPlaced")
            {
                panel.SetActive(true);
                text.gameObject.SetActive(true);
                text.text = "Правилно! ";
            }
            else if (co.tag == "shopPlaced" || co.tag == "schoolPlaced" || co.tag == "hospitalPlaced" || co.tag == "fitnessPlaced" || co.tag == "micPlaced" || co.tag == "shoesPlaced" || co.tag == "policePlaced" || co.tag == "firePlaced" || co.tag == "archPlaced" || co.tag == "programmerPlaced")
            {
                panel.SetActive(true);
                text.gameObject.SetActive(true);
                text.text = "Грешка! Опитайте с друг предмет ";
            }
   
            else
            {
                panel.SetActive(false);
                text.gameObject.SetActive(false);
            }
   
        }
   
        IEnumerator OnTriggerStay(Collider co)
        {
   
            yield return new WaitForSeconds(5);
   
            if (co.tag == "schoolPlaced" || co.tag == "hospitalPlaced" || co.tag == "fitnessPlaced" || co.tag == "micPlaced" || co.tag == "shoesPlaced" || co.tag == "policePlaced" || co.tag == "firePlaced" || co.tag == "archPlaced" || co.tag == "archieoPlaced" || co.tag == "programmerPlaced")
            {
                    panel.SetActive(false);
                    text.gameObject.SetActive(false);
                    gameObject.GetComponent<Pickupable>().enabled = false;
               
            }
        }
   
        void OnTriggerExit(Collider co)
        {
            if (co.tag == "shopPlaced" || co.tag == "schoolPlaced" || co.tag == "hospitalPlaced" || co.tag == "fitnessPlaced" || co.tag == "micPlaced" || co.tag == "shoesPlaced" || co.tag == "policePlaced" || co.tag == "firePlaced" || co.tag == "archPlaced" || co.tag == "archieoPlaced" || co.tag == "programmerPlaced")
            {
                panel.SetActive(false);
                text.gameObject.SetActive(false);
            }
        }

Probably not directly related to your issue, but you should get rid of GameObject.Find and replace it. (Probably with a singleton in this case)

You’re being heavily over-reliant on tags. Again, I don’t know for sure if that’s your problem, but tags tend to make for long lines of unwieldy code and it’s very easy for small mistakes to slip through the crack. I would recommend creating a MonoBehaviour (script) on these objects that currently have those tags (shopPlaced, schoolPlaced, etc), and use variables on that script to track the information you’re currently keeping in tags. Then you can (I’m guessing, though I’d need more info on your project to say for sure) just have a single “bool isPlaced” that gets flipped, and replace those long if statements with

if (co.GetComponent<ThatScriptName>().isPlaced)

(Don’t be stingy with MonoBehaviours; they’re lightweight. If you remove the empty Start() and Update() functions, a MonoBehaviour on an object costs you nothing in terms of performance.)

One last thing that looks like a troublesome point is having OnCollisionStay be a coroutine. OnCollisionStay is called every frame while the things overlap, and if it’s a coroutine, you’re going to have hundreds of those functions running in parallel, and then they’ll all start hitting and undoubtedly causing problems.

I’m not sure what the issue is exactly, but getting these issues cleaned up A) will make your code easier to keep track of (and therefore diagnose the real problem), or B) has a decent chance of fixing the issue on its own.

Actually, watching the gif more closely I believe I know what the issue is (but still fix those other things). Your thing collides with the RIGHT thing, and activates the text; but then it collides with a DIFFERENT thing (floor), which sends your code into the final “else” of your “OnTriggerEnter” function.

Hi! This worked thanks! And thanks for the advices too! For the OnCollisionStay I’m using it as a coroutine because of the fact that if the player place the right item at the right place I need the text to disappear. Same is if the item is on a wrong place!

I’d do that with a timer variable rather than a coroutine; like I said, you’re going to have hundreds of those coroutines running in parallel and messing things up (worse, those coroutines aren’t going to stop after they’re no longer touching, or when it’s touching something else).

Try:

private float collisionEntered = -1f;
void OnTriggerEnter(Collider c) {
if (whatever) {
collisionEntered = Time.time;
}
}

void OnTriggerStay(Collider c) {
if (Time.time > collisionEntered + 5f) {
//deactivate or whatever
}
}

This will avoid those issues with have Stay as a coroutine.