Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

OnColliderEnter counter issues

Discussion in 'Scripting' started by hubali1, Aug 30, 2015.

  1. hubali1

    hubali1

    Joined:
    Aug 30, 2015
    Posts:
    3
    I'm having some trouble getting a counter to work in a space shooter game. The idea is that you need to shoot an asteroid 3 times in order for it to explode. I'm using colliders and if statements to do this but nothing in the actual check for counter works but the if statement checking the collision that it is nested in works fine.



    Code


    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Mover : MonoBehaviour {
    6.  
    7.  
    8.     public float speed;
    9.     public GameObject explosion;
    10.     double counter = 0;
    11.     void Start () {
    12.  
    13.         GetComponent<Rigidbody> ().velocity = transform.forward * speed;
    14.  
    15.  
    16.  
    17.     }
    18.  
    19.     void OnTriggerEnter(Collider other){
    20.  
    21.         if (other.gameObject.tag == "Boundary") {
    22.             GameObject.Destroy(gameObject);
    23.         }
    24.         if (other.gameObject.tag == "Asteroid") {
    25.             counter = counter +1;
    26.             Instantiate (explosion, transform.position, transform.rotation);
    27.             Debug.Log(counter);
    28.             if(counter == 3){
    29.  
    30.                 Instantiate (explosion, transform.position, transform.rotation);
    31.                 GameObject.Destroy(other.gameObject);
    32.                 GameObject.Destroy(gameObject);
    33.  
    34.             }
    35.             Debug.Log(counter);
    36.         }
    37.  
    38.  
    39.  
    40.  
    41.  
    42.     }
    43. }
    44.  
     

    Attached Files:

    • Mover.cs
      File size:
      746 bytes
      Views:
      798
    Last edited: Aug 30, 2015
  2. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    What is this script attached to? & sorry but I don't open google drive attachments as last time I did it was a fake & someone in South Africa tried to log onto my account 10minutes later (google emailed me about it).

    If the asteroid needs to be hit 3 times then I'd place the counter on the asteroid, check if it has been hit by a bullet & then increment the counter.
     
  3. hubali1

    hubali1

    Joined:
    Aug 30, 2015
    Posts:
    3
    It's attached to my bullets. I'm checking if the bullet collides with any asteroids and then using a counter each time it collides. I tried printing the value for counter and nothing in the check for the value of counter (counter == 3) is executing since the counter only goes up to one and no higher.
     
  4. Bradamante

    Bradamante

    Joined:
    Sep 27, 2012
    Posts:
    300
    1) Please use CODE tags.

    2) On first glance the code should work. Are you sure the object are tagged correctly?

    3) Usually a script like this would be on the Asteroids (i.e. the objects to be destroyed), but it can work the way you do it. It's just unusual.

    4) For counter = counter + 1 you would usually write counter++
     
  5. Emre_U

    Emre_U

    Joined:
    Jan 27, 2015
    Posts:
    49
    But if this script is on bullets the counter is also in bullet. Means asteroid does not know about counter. You may want to check about it. I think you should put this counter to astreoid and check for bullets tag. otherwise a bullet hits an asteroid only once and then probably fly to boundry and get killed with counter 1.
     
  6. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    I wouldn't expect this to work, attached to the bullets. You're basically saying that once a bullet has hit something 3 times, whatever it hit should explode, which definitely isn't what you want.

    Don't use numbers of the type 'double' for this purpose, either. Use ints, shorts, or bytes. Double has a ridiculously high range, and you shouldn't make direct comparisons with it either.

    First, create a HitPoint script, and place it each of your asteroids (or if you're creating them at runtime, your asteroid prefab):

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class HitPoints : MonoBehaviour {
    4.  
    5.                        //This Attribute is what makes variables editable in the inspector. public Serializable fields do this automtically, but  get used to using this
    6.     [SerializeField] //attribute, instead. Other scripts wont need to access the explosion prefab of this class, so why make it public?
    7.     GameObject explosion;
    8.  
    9.     [SerializeField]
    10.     byte hitPoints; //a byte is basically an integer with the range 0 - 255. Perfect for this purpose.
    11.  
    12.     public void Damage(byte amount = 1)
    13.     {
    14.         if (amount >= hitPoints) {
    15.             Instantiate (explosion, transform.position, transform.rotation);
    16.             Destroy (gameObject);
    17.         } else
    18.            hitPoints -= amount;
    19.     }
    20.  
    21. }
    22.  
    Refactor so that your OnTriggerEnter code on your Mover looks like this:
    Code (CSharp):
    1.     void OnTriggerEnter(Collider other)
    2.     {
    3.  
    4.         if (other.gameObject.tag == "Boundary") {
    5.             Destroy(gameObject);
    6.             return; // in this case it doesn't matter, but its important to know that Destroy() doesn't work instantly.
    7.                     // of the code in the function will still run. If you're done after a destroy, return out.
    8.         }
    9.      
    10.         //Find a hitpoint component on the other object and damage it if it exists.
    11.         var hp = other.GetComponent<HitPoints>();
    12.         if (!hp)
    13.             hp.Damage();        
    14.      
    15.         Instantiate (explosion, transform.position, transform.rotation);
    16.         Destroy(gameObject);
    17.     }
    Couple of other thoughts:

    Naming Conventions are important. They make it easier for you to organize things in your mind, and for other people to know whats happening if you happen to be working in a group. I would rename your "Mover" component to "Projectile" so that it more accurately describes what the component does.

    Note that you now have TWO different explosion prefabs. One on the Projectile, and one on the Asteroid, which I'm imagining is close to what you were intending. The bullet should explode every time it hits something. The asteroid should explode when it runs out of hitpoints. I'm imagining the bullet explosion should create a smaller explosion than the asteroid one.
     
    Last edited: Aug 30, 2015
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    @OP use code tags in future.
     
  8. hubali1

    hubali1

    Joined:
    Aug 30, 2015
    Posts:
    3
    Sorry, I wasn't really sure how to use code tags but I got it now. I tried switching the code to a class attached to the asteroids and it works now