Search Unity

OnTriggerStay instantiates multiple instead of single objects. Why?!

Discussion in 'Scripting' started by SiMULOiD, Sep 2, 2015.

  1. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    126
    Hi all,

    I am having strange results when I apply this script to my object.
    When the other "rain" object is detected, I get a single instantiation.
    But strangely, when another object is overlapping, I get multiple.
    Can someone give me a clue as to what is happening?

    Thanks,
    Greg




    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6.  
    7. public class OnTriggerStayTimerPitcherPlant : MonoBehaviour {
    8.  
    9.  
    10. public GameObject projectilePrefab;
    11.    float  t = 0;
    12.  
    13.     void OnTriggerEnter(Collider other)
    14.     {
    15.         if(other.gameObject.tag=="Rain")
    16.        
    17.        t = 0;
    18.     }
    19.  
    20.     void OnTriggerStay(Collider other)
    21.     {
    22.        
    23.         if(other.gameObject.tag=="Rain")
    24.  
    25.          t += Time.deltaTime;
    26.          if(t > 3) {
    27.            
    28.  
    29.    
    30.      
    31.       Instantiate(projectilePrefab, transform.position,transform.rotation);
    32.          
    33.  
    34.  
    35.            Destroy(transform.gameObject);
    36.            
    37.          }
    38.     }}
    39.    
    40.  
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    The other object will cause OnTriggerStay to be executed as well and if it's tagged "Rain" on top of that, it's gonna make your script run the code within the if statement too. Calling Destroy(..) destroys the object in the same frame, but not immediately. There's a method that does it, but it's not recommend to use it.
     
    SiMULOiD likes this.
  3. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    126
    Thanks for your reply, but still not understanding why the above works, but unpredictably.
    For example, if I apply the script to my object and introduce the tagged collider object, it works perfectly. However, when another collider is present, I seem to get multiples when the tagged object collides.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I just noticed that the if statements are not nested, so any other object which causes the trigger methods to be called will also instantiate your prefab, not only the ones being tagged with "Rain". I'm not quite sure if that answers your question, probably not. But there's really nothing more to say about it. :S
     
    SiMULOiD likes this.
  5. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    126
    Still having some difficulty getting the above script to work correctly.
    Any other suggestions?
     
  6. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I probably annoy you.

    Anyway, even though you seem to be a bit incoorperative in regards to analyze the problem properly, i'll provide a quick solution. I just wanted you to understand why this happens as you'll face such problems more often and have to learn from that.

    Short explanation, in case you read it:
    You now have a flag that will be set to false as soon as t > 3. This makes sure that only the first call of OnTriggerStay (in the frame where t is greater than 3 for the first time) can instantiate the object. All the others triggering the method will ignore it.

    Have fun.

    Code (CSharp):
    1. public class OnTriggerStayTimerPitcherPlant : MonoBehaviour
    2. {
    3.     public GameObject projectilePrefab;
    4.     float t = 0;
    5.     private bool canInstantiateProjectile = true;
    6.  
    7.     void OnTriggerEnter(Collider other)
    8.     {
    9.         if (other.gameObject.tag == "Rain")
    10.             t = 0;
    11.     }
    12.  
    13.     void OnTriggerStay(Collider other)
    14.     {
    15.  
    16.         if (other.gameObject.tag == "Rain")
    17.             t += Time.deltaTime;
    18.         if (t > 3)
    19.         {
    20.             if (canInstantiateProjectile)
    21.             {
    22.                 Instantiate(projectilePrefab, transform.position, transform.rotation);
    23.                 canInstantiateProjectile = false;
    24.             }
    25.             Destroy(transform.gameObject);
    26.         }
    27.     }
    28. }
     
    Last edited: Sep 4, 2015
    SiMULOiD likes this.
  7. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    126
    Thanks so much for your help, Suddoha! It's nice guys like you that make this forum such a great place to learn.
    I appreciate your time and patience.
     
    Suddoha likes this.