Enemy not following instantiated player, navmeshagent AI

Enemy not following player, navmeshagent AI
Hello, I am having a bit of a problem. It’s not huge I guess as I could just put the player into the scene and everything works fine. However, I would like the player to be able to spawn in.

The problem I am having is if I instantiate the player the enemies won’t follow the player, even after dropping the prefab into the game object. If I drop the player into the scene and then put the player into the game object it works fine though.

Any help is greatly appreciated.

This is my code to grab the gameobject to folow.

using UnityEngine;


public class PlayerManager : MonoBehaviour
{

     #region Singleton

     public static PlayerManager instance;

     private void Awake()
     {
         instance = this;
     }

     #endregion

     public GameObject player;
}

this is the code of the enemyai

 using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
     public float lookRadius = 5f;
     Transform target;
     NavMeshAgent agent;
     private void Start()
     {
         target = PlayerManager.instance.player.transform;
         agent = GetComponent<NavMeshAgent>();       
     }
     private void Update()
     {
         float distance = Vector3.Distance(target.position, transform.position);
         if (distance <= lookRadius)
         {
             agent.SetDestination(target.position);
         }
     }

and this is the code of the instantiate

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnPlayer : MonoBehaviour
{
     [SerializeField]
     private Transform _playerSpawnPos;
     // Start is called before the first frame update
     void Start()
     {
         StartCoroutine(Spawn());
     }
     // Update is called once per frame
     void Update()
     {
        
     }
     IEnumerator Spawn()
     {
         yield return new WaitForSeconds(1.0f);
         PlayerSpawn();
     }
     void PlayerSpawn()
     {
         Instantiate(_playerSpawnPos, new Vector3(-20f, 4.3f, 9.4f), Quaternion.identity);
     }
}

Hi!
I´v run into similar problems a few times and a good way to solve this is to tag your player with the “Player”-tag. Then use mainChar = GameObject.FindWithTag(“Player”) to make a permanent reference to the Player object no matter if it is instantiated or not.

Just remember that FindWithTag is a slower method so you could consider to just reset player stats (like health and stuff) and then transform the player to a spawn point.

Hope this helps!

Change your EnemyAI class so you can pass the reference to the player later:

 using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
     public float lookRadius = 5f;
     Transform target;
     NavMeshAgent agent;
 
     private void Start()
     {
         target = PlayerManager.instance.player.transform;
         agent = GetComponent<NavMeshAgent>();
     }
 
    public void SetTarget(Transform target)
    {
        this.target = target;
    }

     private void Update()
     {
         float distance = Vector3.Distance(target.position, transform.position);
         if (distance <= lookRadius)
         {
             agent.SetDestination(target.position);
         }
     }

Then pass the target to all your enemies if the player spawns (in your SpawnPlayer class):

 void PlayerSpawn()
{
   Transform player = Instantiate(_playerSpawnPos, new Vector3(-20f, 4.3f, 9.4f), Quaternion.identity);
   EnemyAI[] foundEnemyAIs = FindObjectsOfType<EnemyAI>();
   foreach(EnemyAI enemy in foundEnemyAIs)
   {
     enemy.SetTarget(player);
   }
}

PS:
Dont call SetTarget too often (and not every frame) see my code here:

Depending on the Size of the Game and Device, i would not recommend to use “FindObjectsOfType” nor “FindObjectsWithTag” runtime since its pretty slow and expensive