Trying to figure out how to make enemy minions move to correct waypoints.

The minions are spawned from base with this Code

using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class BaseController : MonoBehaviour
{
    GameObject minion;
    float waveTimer = 0f; //  timer that tells base when to spawn enemies.
    float spawnDelay = .5f; // delay between each enemy spawn.
    float waveDelay = 60f; // delay between each wave.
    int numberToSpawn = 10;
    int enemyCount = 0;
    List<Transform> spawnPoints = new List<Transform>();


    private void Awake()
    {
        spawnPoints.Add(transform.Find("BaseSpawn1"));
        spawnPoints.Add(transform.Find("BaseSpawn2"));
        spawnPoints.Add(transform.Find("BaseSpawn3"));
        minion = Resources.Load("Prefabs/Enemy/Minion") as GameObject;
    }

    private void Update()
    {
        if(Time.time >= waveTimer)
        {
            for (int i = 0; i < spawnPoints.Count; i++)
            {
                StartCoroutine(SpawnMinion(spawnPoints[i])); // Starts 1 coroutine for each spawn point               
            }
            waveTimer = Time.time + waveDelay;          
        }
    }

    IEnumerator SpawnMinion(Transform spawnPoint)
    {
        for (int i = 0; i < numberToSpawn; i++)
        {
            Instantiate(minion, spawnPoint.position, Quaternion.Euler(0, 0, 0));
            yield return new WaitForSeconds(spawnDelay); // yields this coroutine for spawnDelay game time
            enemyCount++;
        }
        print(enemyCount);
    }
}

But my problem is trying to get each group of minions to go to correct waypoints. This is gonna be a moba style game with top, mid and bottom lanes. I’m having a time trying to figure out how to get them to go to the correct waypoints, Top group goes to waypoints in top lane, mid ai go to waypoints in mid lane, and well you can guess for the bottom. I really don’t feel like trying to rewrite the spawning script, to achieve this if I don’t have to.

how are you defining the lanes? or how are you setting the minion to a particular lane? I don’t see anything about the waypoint system. where is the list of waypoints?
It like to me you need these basic items defined per minion in order to keep them pointing to correct waypoint.

Each lane has only one waypoint at the mid point between the two bases. And i cant figure how to assign them the waypoint, hints the lack of code. Was trying to attemp this by assigning a script to the minion prefab. But realized that the way they are spawned i had noway to reference one group of minions from the other.

Ill try this later, but maybe if I Instantiate the minions as child of the spawn point. that should group them together in a way I can have child objects(minion) of spawn point A, go to waypoint A. and so on so forth with each spawn point. Would this work? I’ve not started writing it, just thinking to myself atm.

yeh I proto typed a few ideas and one worked, It was a huge mess so I’m rewriting it a little cleaner. Ill post it once done.

Re wrote the minion move Script, but still have a issue. The Minions move to the first way point just fine, but when they reach it the kinda bounce around 5 units away, and never go to the enemy base. Don’t know what to do.
Base Spawn code:

using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class BaseController : MonoBehaviour
{
    GameObject minion;
    float waveTimer = 0f; //  timer that tells base when to spawn enemies.
    float spawnDelay = .5f; // delay between each enemy spawn.
    float waveDelay = 60f; // delay between each wave.
    int numberToSpawn = 10;
    int enemyCount = 0;
    List<Transform> spawnPoints = new List<Transform>();


    private void Awake()
    {
        spawnPoints.Add(transform.Find("BaseSpawn_01"));
        spawnPoints.Add(transform.Find("BaseSpawn_02"));
        spawnPoints.Add(transform.Find("BaseSpawn_03"));
        print(spawnPoints[0].gameObject.name);
        print(spawnPoints[1].gameObject.name);
        print(spawnPoints[2].gameObject.name);
        minion = Resources.Load("Prefabs/Enemy/Minion") as GameObject;
    }

    private void Update()
    {
        if(Time.time >= waveTimer)
        {
            for (int i = 0; i < spawnPoints.Count; i++)
            {
                StartCoroutine(SpawnMinion(spawnPoints[i])); // Starts 1 coroutine for each spawn point               
            }
            waveTimer = Time.time + waveDelay;          
        }
    }

    IEnumerator SpawnMinion(Transform spawnPoint)
    {
        for (int i = 0; i < numberToSpawn; i++)
        {
            Instantiate(minion, spawnPoint.position, Quaternion.Euler(0, 0, 0),spawnPoint);
            yield return new WaitForSeconds(spawnDelay); // yields this coroutine for spawnDelay game time
            enemyCount++;
        }
        print(enemyCount);
    }
}

and the minion move code:

using UnityEngine;
using UnityEngine.AI;

public class EnemyMove : MonoBehaviour
{
    float speed;
    NavMeshAgent navAgent;

    private void Awake()
    {
        navAgent = gameObject.AddComponent<NavMeshAgent>();
    }

    private void Update()
    {
        Move();
    }

    public void Move()
    {

        switch (transform.parent.name)
        {
            case "BaseSpawn_01":
                navAgent.SetDestination(GameObject.Find("WaypointEast_01").transform.position);
                break;
            case "BaseSpawn_02":
                navAgent.SetDestination(GameObject.Find("WaypointWest_01").transform.position);
                break;
            case "BaseSpawn_03":
                navAgent.SetDestination(GameObject.Find("WaypointCenter_01").transform.position);
                break;
        }

        if(navAgent.remainingDistance <= 5)
        {
            if (transform.parent.parent.name == "Base_01")
            {
                navAgent.SetDestination(GameObject.Find("Base_02").transform.position);
            }
            else
            {
                navAgent.SetDestination(GameObject.Find("Base_01").transform.position);

            }
        }
    }

I know my problem is with the if(navAgent.remainingDistance <= 5) code but I’m not for sure what I’m doing wrong.

I think (if I’m reading that correctly), you want to have the minions spawn and go to a spot, right? Do they patrol or something, too? It’s hard to tell. What you want to do is set the destination at the beginning of their travel and in your update function, if they’re < 5 away, set the destination to the new one.
The problem is right now you’re comparing different values in the update loop (which is fast). So, first you’re asking if it’s parent name is something, do an action based on the switch, then you’re setting a new one when it’s close based on “parent.parent.name” and then the next loop is checking … of course, “parent.name” again and setting a destination.
If they are going to just one spot after they spawn or they’re going to a few spots, could you say that if you reply? :slight_smile: That would be easier to offer some suggestions knowing that.

3 lanes, 10 minions spawn ever 60 secs. on spawn they should head to a waypoint in the center of their disenated lane.
which they do, but when they get close they need to continue on to the enemy base. Ive not worked on the attacking yet, just trying to get the movement down. Hope that helps. I’m using the
parent.parent.name to decide which base they spawn at, so they will go to the enemy base. The spawn points are child emptys of the base. and there is two bases, one on each side of the map.
that’s what the if / else statements attempt to do. Probably repeating myself, but I only have 3 waypoints(empty objects), one for each lane. I’m using the opposing bases as the 2nd waypoint for each lane. Its a fairly small map to start, plan on increasing play area once I get the code working. Which will require more waypoints when the lanes become more complex. Thnx for the reply, hope you have a suggestion.

Let’s say they go to the middle point in their lane, then to the base, then … whatever next. (I’m making these assumptions to continue, for now…)
When you create the minion, set their destination once (You can do this with the same code you have in the first part of your ‘move’ method, but do it in Start/Awake (after you’ve got the nav mesh assigned). Then, remove the same code from the ‘move’ method, but keep the remaining code in there that checks for the remainingdistance and sets a new destination. That should do it :slight_smile:

yeh I understand that if we talking about a single object to a multiple way points, but I have 60 minions split into 6 groups all going to different waypoints(3 groups for each base). If I separated the minions into two groups,(group for blue base, group for red base) I could probably fiddle enough to figure it out. but they all run a single move script and that’s the part that’s messing with me. yeh but your assumed correct, top lane minions go to center waypoint in top lane, Center lane goes to center waypoint in center lane, and Bottom to the center waypoint in the bottome lane. Once they reach center, they should head to the opposing base to attack. that’s the end of the movement for them. I understand sending them to first waypoint from the start(), but once there getting them to move to opposing base is making me face palm.
Should I scratch this idea and try to go another route? having the minions run separate scripts depending on their Base they spawn from.

No need to split up the groups. You set the position in Start() using the same statements you had in the first part of the move() to set their destination.
But after you have that portion of the code in Start, erase that portion only from the Move().
Then try to run it :slight_smile:

ill see what I can do. thnx

That worked, thanks for the Ideas
Opposing enemies colliding together throws them off the path/out of the lane, but ill tinker with that.

using UnityEngine;
using UnityEngine.AI;
using System.Collections;

public class EnemyMove : MonoBehaviour
{
    float speed;
    NavMeshAgent navAgent;

    private void Awake()
    {
        navAgent = gameObject.AddComponent<NavMeshAgent>();
    }

    private void Start()
    {
        switch (transform.parent.name)
        {
            case "BaseSpawn_01":
                navAgent.SetDestination(GameObject.Find("WaypointEast_01").transform.position);
                break;
            case "BaseSpawn_02":
                navAgent.SetDestination(GameObject.Find("WaypointWest_01").transform.position);
                break;
            case "BaseSpawn_03":
                navAgent.SetDestination(GameObject.Find("WaypointCenter_01").transform.position);
                break;
        }
    }

    private void Update()
    {
        MoveToBase();
    }

    private void MoveToBase()
    {
        if(navAgent.remainingDistance <= 1f)
        {
            if (transform.parent.parent.name == "Base_01")
                navAgent.SetDestination(GameObject.Find("Base_02").transform.position);
            if (transform.parent.parent.name == "Base_02")
                navAgent.SetDestination(GameObject.Find("Base_01").transform.position);
        }
          
    }
}

You’re welcome. I’m glad that you got it working. Before you were sending them to the base, but you were also sending them back to the middle point – the way your logic was setup (hence the stuttering you experienced as you watched it).