Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Tower defense game arms problem

Discussion in 'Scripting' started by Sabrinedu1993, Oct 7, 2016.

  1. Sabrinedu1993

    Sabrinedu1993

    Joined:
    Sep 24, 2016
    Posts:
    34
    Hi, i have created a tower defense game in unity 5
    it have 2 kind of arms a Missile and a Bullet
    the 2 arms are related by the same script(Bullet)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Bullet : MonoBehaviour
    4. {
    5.     private Transform target;
    6.     public float speed = 70f;
    7.     public float explosionRadius = 0f;
    8.     public GameObject impactEffect;
    9.     // We need a reference to the PlayerStats to add the money
    10.     private PlayerStats playerStats;
    11.     void Start()
    12.     {
    13.         // Get the playerstats
    14.         // This Finds the object with the tag Player then gets the attached PlayerStats component
    15.         playerStats = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerStats>();
    16.     }
    17.     public void Seek(Transform _target)
    18.     {
    19.         target = _target;
    20.     }
    21.     void Update()
    22.     {
    23.         if (target == null)
    24.         {
    25.            Destroy(gameObject);
    26.            return;
    27.         }
    28.         Vector3 dir = target.position - transform.position;
    29.         float distanceThisFrame = speed * Time.deltaTime;
    30.         if (dir.magnitude <= distanceThisFrame)
    31.         {
    32.             HitTarget();
    33.             return;
    34.         }
    35.         transform.Translate(dir.normalized * distanceThisFrame, Space.World);
    36.         transform.LookAt(target);
    37.     }
    38.     void HitTarget()
    39.     {
    40.         GameObject effectIns = (GameObject)Instantiate(impactEffect, transform.position, transform.rotation);
    41.         Destroy(effectIns, 5f);
    42.         if (explosionRadius > 0f)
    43.         {
    44.             Explode();
    45.         }
    46.         else
    47.         {
    48.             Damage(target);
    49.         }
    50.         Destroy(gameObject);
    51.     }
    52.     void Explode()
    53.     {
    54.         Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius);
    55.         foreach (Collider collider in colliders)
    56.         {
    57.             if (collider.tag == "Enemy")
    58.             {
    59.                 Damage(collider.transform);
    60.             }
    61.         }
    62.     }
    63.     void Damage(Transform enemy)
    64.     {
    65.         Destroy(enemy.gameObject);
    66.     }
    67.     void OnDrawGizmosSelected()
    68.     {
    69.      Gizmos.color = Color.red;
    70.         Gizmos.DrawWireSphere(transform.position, explosionRadius);
    71.     }
    72.     void OnCollisionEnter(Collision other)
    73.     {
    74.         // Check if the collision is an enemy
    75.         Debug.Log("In Collision Enter: " + other.gameObject.tag);
    76.         if (other.gameObject.tag == "Enemy")
    77.         {
    78.             // It is, let's add some money
    79.             PlayerStats.Money += 10;      
    80.             Destroy(other.gameObject);
    81.         }
    82.     }
    83. }
    84.  
    the missile have an Explosion Radius =8 and the bullet an Explosion radion =0
    My problem is that my bullet kils one ennemy and that's right but my Missile wich is suposed to kill all the ennemies in it's explosion radius doesn't work and kills only one ennemy
    I wich to fix this and thanks
     
  2. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
    Just looked over your code. Seems like you have two times the same "kill" sequence.

    You check in the Update() function for the Range and Destroy() then.
    But you also do this in OnCollisionEnter()! This is not clean code. I would suggest you should exclude HitTarget() from your update. And instead of calling Destroy(other.gameObject) you should call HitTarget() in OnCollisionEnter().

    That way your Destroy function will be called correctly and not 2 times. ( possible frame dependent null reference )
    Remove:
    Code (CSharp):
    1. if (dir.magnitude <= distanceThisFrame)
    2.         {
    3.             HitTarget();
    4.             return;
    5.         }
    Change:
    Code (CSharp):
    1. void OnCollisionEnter(Collision other)
    2.     {
    3.         // Check if the collision is an enemy
    4.         Debug.Log("In Collision Enter: " + other.gameObject.tag);
    5.         if (other.gameObject.tag == "Enemy")
    6.         {
    7.             // It is, let's add some money
    8.             PlayerStats.Money += 10;    
    9.             HitTarget();
    10.         }
    11.     }
    I am not sure if it's correct but hope it helps! :)
     
    Sabrinedu1993 likes this.
  3. Sabrinedu1993

    Sabrinedu1993

    Joined:
    Sep 24, 2016
    Posts:
    34
    tha
    Thanks a lot i wanna cry mu code works yeeeees.You are genius you had solved 2 problems in my game
    the explosion doesn't work before and now it works i'm so excited
    my only problem now, for exemple when a missile kill more than an ennemy my money rise 10$ the number of ennemies doesn't count in this case
    also the explosion of the missile works but the Bullet explosion doesn't work
    can you solve this please
     
    Last edited: Oct 7, 2016
  4. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Code instantiating it is the same, so I'd start with checking the prefab you're instantiating.

    Adding money is called from OnCollisionEnter, which happens only once. You can move it to your Damage method (so only damaged enemies will give money) and later in the project from the Bullet to the Enemy (f.e. in a Die method, or OnDestroy or where it will fit logically).
     
    Sabrinedu1993 likes this.
  5. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    You should try to have objects handle their own attributes. For example, you shouldn't have the player handle killing enemies. You should just have them tell the enemy: "I damaged you *this* much", and let the enemy determine if it dies or not. By that same notion when an enemy dies it should tell the player object I'm dead, and I'm worth this much money. The player object can then add the money ( Maybe you added a bonus to the player that doubles his money for 10 seconds, the enemy wouldn't know that. So it should let the player do all the money handling:

    I've modified the code slightly to add the idea that Enemeis have health. So maybe 1 bullet doesn't kill them exactly. You can still use this idea, and have most of the game work the same by having enemies have less health than your bullets do.

    In the enemy script something like this:
    Code (CSharp):
    1. GameObject player;
    2. private float currentHealth = 1f;
    3. private float value = 10f;
    4.  
    5. void Start()
    6. {
    7.        player = GameObject.FindGameObjectWithTag("Player");
    8. }
    9.  
    10. public void DamageMe(float damage)
    11. {
    12.           currentHealth-=damage;
    13.           if (currentHealth <=0)
    14.           {
    15.                   Destroy(this.gameObject);
    16.                   player.GiveMoney(this.value); // set to 10 in your example
    17.           }
    18. }
    19.  
    Then in the player code:
    Code (CSharp):
    1. void OnCollisionEnter(Collision other)
    2.     {
    3.         // Check if the collision is an enemy
    4.         Debug.Log("In Collision Enter: " + other.gameObject.tag);
    5.         if (other.gameObject.tag == "Enemy")
    6.         {
    7.            // Don't add Money here
    8.            // delete this line below
    9.            // PlayerStats.Money += 10;
    10.             HitTarget();
    11.         }
    12.     }
    13.  
    14. // Enemies that die call this function to tell us how much they were worth
    15. public void GiveMoney(float amount)
    16. {
    17.    PlayerStats.Money+=amount;
    18. }
    19.  
    20. // Right now you don't have damage ratings for your weapons
    21. // but this lets you add it later if you want
    22. void Damage(Transform enemy,float damage = 10f)
    23. {
    24.       enemy.gameObject.DamageMe(damage);
    25. }
    26.  
     
    Sabrinedu1993 likes this.
  6. Sabrinedu1993

    Sabrinedu1993

    Joined:
    Sep 24, 2016
    Posts:
    34
    than
    thanks a lot the money problem is solved now but fot the explosion can you please detail your answer i don't know what to do and thanks
     
  7. Sabrinedu1993

    Sabrinedu1993

    Joined:
    Sep 24, 2016
    Posts:
    34
    so now my only problem is the Bullet exploion wich doesn't work also i have discovered when the number of balls raise the balls can get out of them target like this i have balls flying and getting out of the screen i have a rigid body for my balls with use gravity
     

    Attached Files:

    • q.PNG
      q.PNG
      File size:
      99.8 KB
      Views:
      571
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Create a Box Collider around your entire game. When something collides with it destroy that object.
     
    Sabrinedu1993 likes this.
  9. Sabrinedu1993

    Sabrinedu1993

    Joined:
    Sep 24, 2016
    Posts:
    34
    look at my balls when i didn't kill them
    if i have many balls in the screen they will act like this
    my balls misses fluency when they move also my for loop is infinite every 5 second the number of ball that go out is incremented and the loop is infinite
    when i have many balls i get this mess
     

    Attached Files:

    • q.PNG
      q.PNG
      File size:
      145.5 KB
      Views:
      663