Assigning Waypoints to an instantiated enemy

Hi,

I have a ‘Boss’ that instantiates itself when all enemies are defeated. Here is the JS (attached to each enemy):

public static var enemyCount : int = 3;
 
function OnCollisionEnter( collision : Collision ) 
 {
      if(collision.gameObject.tag == "fireball")
      {
      animation.Play("dying");
      audio.Play();
 yield WaitForSeconds(0.2);
         GameObject.Destroy ( gameObject ) ;
         enemyCount -= 1;
}
if(enemyCount <= 0) {
var instance : GameObject = Instantiate(Resources.Load("boss"));
  }
}

I also have a C# script that deals with enemies patrolling Waypoints and chasing the player if they wander within a certain distance from the player. This script is also attached to the enemies, as well as the boss himself. However, I cannot assign Waypoints to the boss like I can to the other enemies. From researching I’ve read you cannot do this to instantiated objects.

Is there any way around this? Your help would be much appreciated. Many thanks!

EDIT: C# script for Waypoint finding and player chasing/attacking:

using UnityEngine;
using System.Collections;

public class EnemyMovementController : MonoBehaviour 
{
	// speed of the AI player
	public int speed = 4;
	
	// speed the ai player rotates by
	public int rotationSpeed = 5;
	
	// the waypoints
	public Transform[] waypoints;
	
	// current waypoint id
	private int waypointId = 0;
	
	// the character controller component
	private CharacterController characterController;

	private Transform player;

	public int chasingDistance = 30;

	private bool attacking = false;

	/**
        Init
    */
	void Start()
	{
				// retrieve this GameObjects CharacterController Component and store in characterController (todo)
		characterController = gameObject.GetComponent<CharacterController>();
		player = Motor.Instance.transform;
	}
	
	/**
        Patrol around the 		waypoints
    */
	void Patrol()
	{
		// if no waypoints have been assigned
		if (waypoints.Length == 0) 
		{
			//Debug.LogError("You need to assign some waypoints within the Inspector!");
			return;
		}
		
		// if distance to waypoint is less than 2 metres then start heading toward next waypoint
		if (Vector3.Distance(waypoints[waypointId].position, transform.position) < 2)
		{
			// increase waypoint id
			waypointId++;
			
			// make sure new waypointId isn't greater than number of waypoints
			// if it is then set waypointId to 0 to head towards first waypoint again
			if (waypointId >= waypoints.Length) waypointId = 0;
		}
		
		// move towards the current waypointId's position
		MoveTowards(waypoints[waypointId].position);
		attacking = false;
	}
	
	/**
        Update - Every Frame
    */
	void Update()
	{

		PatrolAndChase ();
		}
			
	
	/**
        Move towards the targetPosition
    */
	void MoveTowards(Vector3 targetPosition)
	{
		// calculate the direction to waypoint
		Vector3 direction = targetPosition - transform.position;
		
		// rotate over time to face the target rotation - Quaternion.LookRotation(direction)
		transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
		
		// set the x and z axis of rotation to 0 so the agent stands upright (otherwise equals REALLY bad leaning)
		transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
		
		// use the CharacterController Component's SimpleMove(...) function
		// multiply the agent's forward vector by the speed to move the AI
		characterController.SimpleMove(transform.forward * speed);
		
		// crossfade the walking animation (todo)
		animation.CrossFade("walking",0.2F);
		
	}
	void PatrolAndChase()
	{
				// calculate the distance to the player
				int distanceToPlayer = (int)Vector3.Distance (player.transform.position, transform.position);
		
				// calculate vector direction to the player
				Vector3 directionToPlayer = transform.position - player.transform.position;
		
				// calculate the angle between AI forward vector and direction toward player
				// we use Mathf.Abs to store the absolute value (i.e. always positive)
				int angle = (int)Mathf.Abs (Vector3.Angle (transform.forward, directionToPlayer));
		
				// if player is within 30m and angle is greater than 130 then begin chasing the player
				if (distanceToPlayer < chasingDistance && angle > 130) {
						// move towards the players position
						//MoveTowards (player.transform.position);
			
						// attack the player ONLY if not already attacking
						if (!attacking && distanceToPlayer < 4) {
								StartCoroutine (Attack ());
						} else if (!attacking) {
								// player is "out of sight"
								MoveTowards (player.transform.position);
						}
				} else {
						// patrol
						Patrol ();
			
						// if attacking, then toggle to stop
			
				}

		}

		/**
    Fire at the player
*/
	IEnumerator Attack()
	{
		// toggle attacking on
		attacking = true;
		
		// crossfade the attacking animation
		animation.CrossFade("jump", 0.2F);
		
		// odds of player being attacked successfully
		float odds = Random.Range(0.0f, 1.0f);
		
		// was the player attacked?
		if (odds >= 0.0f)
		{
			// player has been attacked
			HealthController.Instance.HasBeenAttacked();
		}
		
		// create delay before attacking again (else would be constant every frame = dead player)
		yield return new WaitForSeconds(1);

		
		// allow attacking again
		attacking = false;
	}
}

Okay you have two options.

I’ll write and advice before writing options. Instead of controlling enemy count on every enemy object, create an EnemyController.cs script and add an empty gameobject called Enemy_Manager. This script should contain the information of how many enemies left on your game. The following script considers all of your enemies has “Enemy” tag.

    **Enemy Controller Class**[c#]
    public int enemyCount;
    GameObject enemies[];
    void Start()
    {
    enemies = GameObject.FindGameObjectsWithTag("Enemy");
    enemyCount = enemies.Length;

    }
    public void ModifyEnemyCount()
    {
    enemyCount --;
        if (enemyCount == 0)
        {
            //DoSomething.
        }
   }

After then if your enemies die, they should decrease this value. So you should modify your EnemyDead.js script as:

function OnCollisionEnter( collision : Collision ) 
 {
      if(collision.gameObject.tag == "fireball")
      {
      animation.Play("dying");
      audio.Play();
 yield WaitForSeconds(0.2);
         GameObject.Destroy ( gameObject ) ;
         var enemyCont : EnemyController = GameObject.Find("Enemy_Manager").GetComponent<EnemyController>();
         enemyCont.ModifyEnemyCount();
}

This way you now have a centralised enemy control system that you can do other things too. Now to your problem’ solution.

First Option:

Add your boss before you start the game, add the waypoints and disable his GameObject. When all the enemies are defeated, enable his GameObject. So basically what you want to do is on your ModifyEnemyCount method, you want to enable your boss’s gameobject. So;

 public void ModifyEnemyCount()
        {
        enemyCount --;
            if (enemyCount == 0)
            {
                GameObject boss = GameObject.Find("boss");
                boss.enabled = true;
            }
        }

Second Option:

You need a waypoint manager just like enemy manager we did back there. So add an empty gameobject called Waypoint_Manager and attach a script called WaypointController.

**Waypoint Controller Class**[c#]
public Transform[] waypoints;

Attach your waypoints to this object and do the following within the EnemyMovementController.cs script:

public class EnemyMovementController : MonoBehaviour 
{
    // speed of the AI player
    public int speed = 4;
 
    // speed the ai player rotates by
    public int rotationSpeed = 5;
 
    // the waypoints
    Transform[] waypoints;  // NO NEED FOR THIS TO BE PUBLIC ANYMORE
 
    // current waypoint id
    private int waypointId = 0;
 
    // the character controller component
    private CharacterController characterController;
 
    private Transform player;
 
    public int chasingDistance = 30;
 
    private bool attacking = false;
 
    WaypointController waypointScript; //TO REFERENCE OUR NEW SCRIPT
    /**
        Init
    */
    void Start()
    {
          // retrieve this GameObjects CharacterController Component and store in characterController (todo)
       characterController = gameObject.GetComponent<CharacterController>();
       player = Motor.Instance.transform;
       waypointScript = GameObject.Find("Waypoint_Manager").GetComponent<WaypointController>(); // get the WaypointController script on Waypoint_Manager gameobject within our waypointScript variable.
       waypoints = waypointScript.waypoints; // assign our centralised waypoints from WaypointController to enemies' waypoints.
    }

Note that I didn’t test the scripts, just wrote them here, there might be some errors but you should be able to fix them if happens. If not, please ask again.
I hope this helps.

Store all your instantiated enemies in a list, and remove them if they are destroyed. If they are in the list, they can be accessed either by their index number in the list or by using List.Contains() and comparing the enemy you want to access to the list’s contents.