Search Unity

Enemies Moving Back To The Start Of A Waypoint System

Discussion in 'Scripting' started by Jdools05, Jan 20, 2019.

  1. Jdools05

    Jdools05

    Joined:
    Nov 21, 2018
    Posts:
    3
    Hello Unity community! I am just starting out working with unity and c# and I was wondering if you could help me out on a problem. I'm building a tower defense game and I'm using a waypoint system to move my enemies along a set path. My enemies break into weaker enemies if they sustain enough damage. I'm trying to go for a Bloons Tower Defense feel. However once my enemies break, the new enemies go back to the start of the waypoints and I don't want that. I've used NavMesh and NavMeshAgents and got it to work but I don't like how it reacts to the environment of my game. Any help would be greatly appreciated. Thanks in advance for the help. Below are my Waypoint, Enemy Movement, and Enemy script. If you need more info, please ask.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Waypoints : MonoBehaviour {
    4.  
    5.     public static Transform[] points;
    6.  
    7.     private void Awake()
    8.     {
    9.         points = new Transform[transform.childCount];
    10.         for (int i = 0; i < points.Length; i++)
    11.         {
    12.             points[i] = transform.GetChild(i);
    13.         }
    14.     }
    15.  
    16. }
    Code (CSharp):
    1. using UnityEngine;
    2. [RequireComponent(typeof(Enemy))]
    3. public class EnemyMovement : MonoBehaviour {
    4.  
    5.     public float speed = 10f;
    6.     private Transform target;
    7.     private int wavepointIndex = 0;
    8.  
    9.     void Start()
    10.     {
    11.         target = Waypoints.points[0];
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.         Vector3 dir = target.position - transform.position;
    17.         transform.Translate(dir.normalized * speed * Time.deltaTime, Space.World);
    18.         if(Vector3.Distance(transform.position, target.position) <= 0.2f)
    19.         {
    20.             GetNextWaypoint();
    21.         }
    22.     }
    23.  
    24.     void GetNextWaypoint()
    25.     {
    26.         if (wavepointIndex >= Waypoints.points.Length - 1)
    27.         {
    28.             PlayerStats.Lives--;
    29.             Destroy(gameObject);
    30.         }
    31.         wavepointIndex++;
    32.         target = Waypoints.points[wavepointIndex];
    33.     }
    34. }
    Code (CSharp):
    1. using UnityEngine.UI;
    2. using UnityEngine;
    3.  
    4. public class Enemy : MonoBehaviour {
    5.  
    6.     public float startSpeed = 10f;
    7.     [HideInInspector]
    8.     public float speed;
    9.     public float startHealth = 100;
    10.     private float health;
    11.     public int worth = 25;
    12.     public int index;
    13.     public GameObject EnemyDeathEffect;
    14.     public GameObject BreakTo;
    15.     [Header("Unity Stuff")]
    16.     public Image healthBar;
    17.     private bool isDead;
    18.     public EnemyMovement enemyMovement;
    19.  
    20.     void Start()
    21.     {
    22.         speed = startSpeed;
    23.         health = startHealth;
    24.     }
    25.  
    26.     public void TakeDamage(float amount)
    27.     {
    28.         health -= amount;
    29.  
    30.         healthBar.fillAmount = health / startHealth;
    31.  
    32.         if (health <= 0 && !isDead)
    33.         {
    34.             if (index <= 1)
    35.             {
    36.                 Die();
    37.             }
    38.             else
    39.             {
    40.                 Break();
    41.             }
    42.         }
    43.     }
    44.  
    45.     public void Slow (float pct)
    46.     {
    47.         enemyMovement.speed = startSpeed * (1f - pct);
    48.     }
    49.  
    50.     void Die ()
    51.     {
    52.         isDead = true;
    53.         PlayerStats.Money += worth;
    54.         Destroy(gameObject);
    55.         GameObject effect = (GameObject)Instantiate(EnemyDeathEffect, transform.position, transform.rotation);
    56.         WaveSpawner.EnemiesAlive--;
    57.         Destroy(effect, 2f);
    58.     }
    59.  
    60.     public void Break()
    61.     {
    62.         isDead = false;
    63.         PlayerStats.Money += worth;
    64.         Destroy(gameObject);
    65.         GameObject effect = (GameObject)Instantiate(EnemyDeathEffect, transform.position, transform.rotation);
    66.         GameObject enemy = (GameObject)Instantiate(BreakTo, transform.position, transform.rotation);
    67.         index--;
    68.         Destroy(effect, 2f);
    69.     }
    70. }
     
  2. NicBischoff

    NicBischoff

    Joined:
    Mar 19, 2014
    Posts:
    204
    1. void Start()
    2. {
    3. target = Waypoints.points[0];
    4. }

      You are setting their target to 0 when they start so they will ‘start’ at 0 in the waypoints array. When they die you need to cache their current node and pass that onto your instanciated game object.
     
  3. Jdools05

    Jdools05

    Joined:
    Nov 21, 2018
    Posts:
    3
    Thanks for the help but like I said I'm new to all of this so is there an easy way to carry over the waypoint value? How would I set this up in my code?
     
  4. NicBischoff

    NicBischoff

    Joined:
    Mar 19, 2014
    Posts:
    204
    I'm doing this on mobile so it is hard to scroll your code but I surmise it something like this.
    You basically want to set the new enemy starting waypoint to the old enemy waypoint id before destroying it.


    Code (CSharp):
    1.  
    2.  
    3. //----- EnemyMovement Class
    4.  
    5. public int wavepointIndex = 0; // made public - there are many ways to do this, I am just going with the simplest.
    6.  
    7. void Start()
    8. {
    9.        target = Waypoints.points[wavepointIndex]; // Set the starting index to the wavepointindex above, so it would be 0 by default but it can be set from another script.
    10. }
    11.  
    12. //----- Enemy Class
    13.  
    14.     public void Break()
    15.     {
    16.         isDead = false;
    17.         PlayerStats.Money += worth;
    18.         GameObject effect = (GameObject)Instantiate(EnemyDeathEffect, transform.position, transform.rotation);
    19.  
    20.         GameObject enemy = (GameObject)Instantiate(BreakTo, transform.position, transform.rotation);
    21.       enemy.GetComponent<EnemyMovement>().wavepointIndex = enemyMovement.wavepointIndex; // Set value of NEW enemy to the old position.
    22.  
    23.         index--;
    24.         Destroy(effect, 2f);
    25.  
    26.         Destroy(this.gameObject); // Moved this here so that you can ensure all your code executes before destroying the object and scrips etc.
    27.     }
    28.  
    29.  
    30.  
    Once you get it all working, maybe look at pooling rather than destroying and instantiating everything. This way you can reuse your objects.
     
    Last edited: Jan 21, 2019
  5. Jdools05

    Jdools05

    Joined:
    Nov 21, 2018
    Posts:
    3
    Thanks so much! Works like a charm! Glad you could help :D
     
    NicBischoff likes this.