Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Ghosthunter_007 · Oct 05, 2021 at 09:25 AM · instantiateprefabmissingreferenceexception

When the player dies and I reload the scene the enemies spawn script stops working.

This is my first game and I'm trying to reset the game after player death, i already made the ui and all the functions but for some reason after the player dies and reloads the scene the enemy manager stops respawning my enemy prefab after I kill it once. The error message appears when I try to instantiate the new enemy. The error message is. "MissingReferenceException: The object of type 'EnemyManager' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. EnemyManager.spawnNewEnemy () (at Assets/EnemyManager.cs:35) target.g__Die|26_0 () (at Assets/target.cs:116) target.TakeDamage (System.Single amount) (at Assets/target.cs:103) gun.Shoot () (at Assets/gun.cs:59) gun.Update () (at Assets/gun.cs:34)"


target.cs

 public class target : MonoBehaviour
 {
     public float health = 30f;
 
     public NavMeshAgent agent;
 
     public Transform player;
 
     public LayerMask whatIsGround, whatIsPlayer;
 
     public HealthbarEnemy healthbar;
 
     public delegate void EnemyKilled();
     public static event EnemyKilled OnEnemyKilled;
 
     //Patroling
     public Vector3 walkPoint;
     bool walkPointset;
     public float walkPointRange;
 
     //Attacking
     public float timeBetweenAttacks;
     public float agentDamage = 50f;
     bool alreadyAttacked;
 
     //State
     public float sightRange, attackRange;
     public bool playerInSightRange, PlayerInAttackRange;
 
     private void Awake()
     {
         player = GameObject.Find("First Person Player").transform;
         agent = GetComponent<NavMeshAgent>();
     }
 
     public void Patroling()
     {
         if (!walkPointset)
         {
             SearchWalkPoint();
         }
         if (walkPointset)
         {
             agent.SetDestination(walkPoint);
         }
         Vector3 distaneTowalkPoint = transform.position - walkPoint;
 
         if (distaneTowalkPoint.magnitude < 1f)
         {
             walkPointset = false;
         }
 
     }
 
     private void SearchWalkPoint()
     {
         float randomZ = Random.Range(-walkPointRange, walkPointRange);
         float randomX = Random.Range(-walkPointRange, walkPointRange);
 
         walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, 
         transform.position.z + randomZ);
         if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround))
         {
             walkPointset = true;
         }
     }
 
     public void ChasePlayer()
     {
         agent.SetDestination(player.position);
     }
 
     public void AttackPlayer()
     {
         agent.SetDestination(transform.position);
 
         transform.LookAt(player);
         if (!alreadyAttacked)
         {
             //attack code here
             player.GetComponent<playerDamage>().damagePlayer(agentDamage);
 
 
 
             alreadyAttacked = true;
             Invoke(nameof(ResetAttack), timeBetweenAttacks);
         }
     }
 
     private void ResetAttack()
     {
         alreadyAttacked = false;
     }
 
     public void TakeDamage (float amount)
     {
         health -= amount;
         healthbar.SetHealth(health);
         if(health <= 0f)
         {
            Die();
         }
 
         void Die()
         {
             Debug.Log("this needs to be excuted");
             if (gameObject != null)
             {
                 Debug.Log("this needs to be excuted");
                 Destroy(gameObject);
                 Debug.Log("this was excuted successfully");
             }
             Debug.Log("this needs to be excuted");
             OnEnemyKilled();
             Debug.Log("this was excuted successfully");
         }
     }
 
     private void Update()
     {
         player = GameObject.Find("First Person Player").transform;
         agent = GetComponent<NavMeshAgent>();
         //Check for sight and attack range
         playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
         PlayerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);
 
         if(!playerInSightRange && !PlayerInAttackRange)
         {
             Patroling();
         }
 
         if (health < 30f)
         {
             ChasePlayer();
         }
 
         if (playerInSightRange && !PlayerInAttackRange)
         {
             ChasePlayer();
         }
 
         if (playerInSightRange && PlayerInAttackRange)
         {
             AttackPlayer();
         }
     }
 
     private void OnDrawGizmosSelected()
     {
         Gizmos.color = Color.red;
         Gizmos.DrawWireSphere(transform.position, attackRange);
         Gizmos.color = Color.yellow;
         Gizmos.DrawWireSphere(transform.position, sightRange);
     }
     
 }

gun.cs

 public class gun : MonoBehaviour
 {
     public float damage = 10f;
     public float range = 100f;
     public float fireRate = 15f;
     public float impactForce = 3000f;
 
     public AudioSource soundSource;
     public AudioClip gunschot;
     public Camera fpsCam;
     public ParticleSystem muzzleFlash;
     public GameObject impactEffectBlood;
     public GameObject impactEffectGround;
     public pausmenu pausmenu;
 
     private float nextTimeToFire = 0f;
 
     void Start()
     {
         soundSource = GetComponent<AudioSource>();
         impactEffectBlood.SetActive(true);
         impactEffectGround.SetActive(true);
     }
 
     // Update is called once per frame
     void Update()
     {
         if (Input.GetButtonDown("Fire1") && Time.time >= nextTimeToFire && !pausmenu.GameIsPaused)
         {
             nextTimeToFire = Time.time + 1f / fireRate;
             Shoot();
         }
         
     }
 
     void playgunsound ()
     {
         soundSource.clip = gunschot;
         soundSource.PlayOneShot(soundSource.clip);
     }
 
     void Shoot()
     {
         
         playgunsound();
         muzzleFlash.Play();
 
         RaycastHit hit;
         if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
         {
             Debug.Log(hit.transform.name);
 
             target target = hit.transform.GetComponent<target>();
             if(target != null)
             {
                 target.TakeDamage(damage);
             }
 
             if (hit.rigidbody != null)
             {
                 hit.rigidbody.AddForce(-hit.normal * impactForce);
             }
 
             if (hit.transform.name == "Enemy")
             {
                 GameObject impactGO = Instantiate(impactEffectBlood, hit.point, 
                 Quaternion.LookRotation(hit.normal));
                 Destroy(impactGO, 2f);
             }
 
             if (hit.transform.tag == "ground")
             {
                 GameObject impactGO = Instantiate(impactEffectGround, hit.point, 
                 Quaternion.LookRotation(hit.normal));
                 Destroy(impactGO, 2f);
             }
             
         }
     }
 }
 

EnemyManager.cs

 public class EnemyManager : MonoBehaviour
 {
     
     public Transform spawnpoint;
     public GameObject EnemyPrefab;
 
     // Start is called before the first frame update
     void Start()
     {
         Debug.Log("this needs to be excuted");
         spawnNewEnemy();
         Debug.Log("this was excuted successfully");
     }
 
     void OnEnable()
     {
         Debug.Log("this needs to be excuted");
         target.OnEnemyKilled += spawnNewEnemy;
         Debug.Log("this was excuted successfully");
     }
 
     // Update is called once per frame
     void Update()
     {
         
     }
 
     void spawnNewEnemy()
     {
         Debug.Log("this needs to be excuted");
         if (transform != null)
         {
             Debug.Log("this needs to be excuted");
             Debug.Log(transform);
             Instantiate(EnemyPrefab, spawnpoint.transform.position, Quaternion.Euler(Vector3.zero));
             Debug.Log("this was excuted successfully");
         } else
         {
             Debug.Log("ENEMYMANAGER.TRANSFORM = NULL");
         }
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Ghosthunter_007 · Oct 05, 2021 at 07:59 AM

@simiel7 Thanks I will definitely read up on that. But i never call Destroy() on the enemy manager object. I can show you more of my code.


this is all the code that's involved with the scene load. (Plus the code from before of course)

 public class GameOver : MonoBehaviour
 {
     public void PlayAgain()
     {
         Debug.Log("this needs to be excuted");
         SceneManager.LoadScene(1, LoadSceneMode.Single);
         Debug.Log("this was excuted successfully");
     }
 
     public void BackToMain()
     {
         Debug.Log("this needs to be excuted");
         SceneManager.LoadScene(0, LoadSceneMode.Single);
         Debug.Log("this was excuted successfully");
     }
 
     public void QuitGame()
     {
         Debug.Log("quit");
         Application.Quit();
     }
 }
 
 public class playerDamage : MonoBehaviour
 {
     public float healthplayer = 100f;
     public float currentHealth;
 
     public Healthbar healthbar;
     public GameObject GameOverUI;
     public pausmenu pausmenu;
 
     void Start()
     {
         currentHealth = healthplayer;
         healthbar.SetMaxHealth(healthplayer);
         
     }
   
 
     
     public void damagePlayer(float amount)
     {
         currentHealth = healthplayer -= amount;
 
         healthbar.SetHealth(currentHealth);
 
         if (currentHealth > 0)
         {
             Debug.Log("you took damage, your health is now:" + currentHealth);
         }
 
         if (currentHealth <= 0f)
         {
             Die();
         }
 
         void Die()
         {
             Debug.Log("you took health has been depleted you are dead");
             Cursor.lockState = CursorLockMode.Confined;
             GameOverUI.SetActive(true);
             Time.timeScale = 0f;
         }
     }
 }

I've also tried to fix the problem by adding some lines that refer to both the spawnpoint object and the enemy prefab in the start and spawn new enemy functions but that made the game spawn one extra enemy for every time I run the game over sequence. Other than that I haven't changed anything.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image simiel7 · Oct 05, 2021 at 07:33 PM 1
Share

@Ghosthunter_007

You have this line of code in the EnemyManager:

      void OnEnable()
      {
          Debug.Log("this needs to be excuted");
          target.OnEnemyKilled += spawnNewEnemy;
          Debug.Log("this was excuted successfully");
      }

Could you try to add target.OnEnemyKilled -= spawnNewEnemy; into the OnDisable() method, for example:

 void OnDisable()
          {
              Debug.Log("this needs to be excuted");
              target.OnEnemyKilled -= spawnNewEnemy;
              Debug.Log("this was excuted successfully");
          }


Either way if it not fix this issue, you should always remove the delegation reference or event listeners if you add them, because it can cause issues later, also it will cause memory leak. So a best practice is if you use xyz.AddListener(...) or xyz += something, then you should think about the de-registration of them, like in the OnDestroy() or OnDisable() or where it is fit into your logic.

Maybe you have luck with it and this is your problem too. And try to revert back the additional code you added as a temporary fix.

Under the hood, I think when the scene loads, it will leave the previous registration as is (because you did not de-registered it) and your logic will just add a new one with the target.OnEnemyKilled += spawnNewEnemy;, but technically, your first version is not exists anymore. So if you remove the first one as I mentioned it can solve this problem.
And when you call OnEnemyKilled(); in the target class, it will iterate through all the registered delegation and the first one is null, because the scene was unloaded and that specific gameobject was destroyed automatically. This is why you need to remove it and the OnDisable() or OnDestory() will be called automatically when the scene unloaded, it will technically delete everything (if you use the SceneManager with LoadSceneMode.Single).

avatar image Ghosthunter_007 simiel7 · Oct 06, 2021 at 06:52 AM 0
Share

@simiel7 IT WORKED! THANK YOU SO MUCH!!

avatar image simiel7 Ghosthunter_007 · Oct 07, 2021 at 07:27 PM 0
Share

Glad to hear, your welcome :)

avatar image
1

Answer by simiel7 · Oct 04, 2021 at 04:39 PM

Hi!

As I can see, you left out some part of your code, but in general this error means what it says. You destroyed the EnemyManager at some point with the Destroy(...) method and cannot find the reference anymore.

Another possibility, you mentioned that the player dies and the Scene reloads. Maybe here you implemented something which will destory the EnemyManager or not recreate it automatically and when the game restarts itself, the EnemyManager not yet created and this is the result of it.

I cannot point out the exact problem, because as I said it seems to me that this is not the full code where the restarting process happens or the player dies (or I missed them entirely, sorry for that).

But either way, this error appears if you or the system destroyed the gameobject and the class cannot be found anymore. In the latter case, you should check out the Unity's lifecycle process (https://docs.unity3d.com/2021.1/Documentation/Manual/ExecutionOrder.html) and get your head around it, because during resetting the scene improperly can lead to this problem, where Unity already destroyed your object (properly), but the starting process you wrote is flawed and will not recreate the object you need.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

181 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I stop infinite instantiation? 1 Answer

Instantiating prefabs as child of a gameobject 1 Answer

Object after instantiate doesn't apply AddForce 1 Answer

How to access property of a prefab before Instantiating. 1 Answer

Spawn blood particle system prefab where sword hits enemy 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges