Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
This question was closed Feb 04, 2018 at 06:54 AM by Dragonrider-Liu for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Dragonrider-Liu · Feb 03, 2018 at 03:14 PM · scripting problemscript.script errorinstances

When call the instances of prefab, got the NullReferenceException warnings while the code functioned properly

Hello there.

I learned the Space Shooter tutorial, and made some changes to produce something different. I want a constant respawning, and the instances are called by a script not bound to the prefab. And the enemies move toward the players.

For most parts I succeeded, but when I assigned the instances to array with Enemy[Num]=(GameObject)instantiate(prefab, position, rotation), I got "UnassignedReferenceException: The variable Prefab of Fight has not been assigned.". After the instantiation of the first clone, nothing happened. (well, the timer did work properly and I can control the player...)

Then, I use an intermediate to get the instance generated in each cycle, and assign it to Enemy[Num], this work well. But when I call the instances stored in Enemy[] in update(), well, in fact, the function (movement toward player) worked properly, however I got hundreds warnings (NullReferenceException: Object reference not set to an instance of an object) .

I am curious why I can't assign (GameObject)isntantiate(bla,bla,bla) to Enemy[Num] directly,

and why though the function worked, there are so many warnigs or errors for the movement code?

And how to solve it?

Thank you in advance.

Here's the code:

     //Only the lines related to this problem copied. Code for other parts like the  Player-related code are not included.
 using System;
 using System.Collections;
 using UnityEditor;
 using UnityEngine;
 using Random = UnityEngine.Random;
     
     public class Fight : MonoBehaviour
     {
         public GameObject[] Foes;
         public float spawnWait;
         private int Num=0;
         private Vector3 _spawnPosition=new Vector3();
         private float foeStep;
         public float FoeSpeed;
         private GameObject[] Enemy;
         public GameObject Prefab;
         
     
     void Start () {
             Enemy=new GameObject[5];
             StartCoroutine (SpawnWaves ());
     }
     
     void Update () {
             foeStep = FoeSpeed * Time.deltaTime;
             foreach (var foe in Enemy) //No warning for this line.
             {
                 foe.transform.position = Vector3.MoveTowards(foe.transform.position, Player.transform.position, foeStep);  //The warning "NullReferenceException: Object reference not set to an instance of an object" pointed to this line. However, this code's function worked properly.
             }
     }
     
         IEnumerator SpawnWaves ()
         {
             while (true)
             {
                 Quaternion spawnRotation = Quaternion.identity;
                 for (;;)
                 {
                     GameObject foe = Foes [Random.Range (0, Foes.Length)];
                     foe.name = Num.ToString();
                     do
                     {
                         _spawnPosition = new Vector3 (Random.Range (-13f,13f), Random.Range (-4.8f,4.8f), 0);
                     }while(Vector3.Distance (_spawnPosition,Player.transform.position)<0.7f);
                     Prefab=(GameObject)Instantiate (foe, _spawnPosition, spawnRotation);
     
     //Enemy[Num]=(GameObject)Instantiate (foe, _spawnPosition, spawnRotation);  //If use this code (without the later "Enemy[Num] = Prefab;" will only spawn one enemy and a warning described above. Why?
     
                     spawnWait=Mathf.Min(1,10/Time.time);
                     Enemy[Num] = Prefab;
                     Array.Resize<GameObject>(ref Enemy, Enemy.Length +1);
                     Num++;
                     Debug.Log(Prefab.name); // This line work well.
                     yield return new WaitForSeconds (spawnWait);
                 }
             }
         }
     
     }
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

1 Reply

  • Sort: 
avatar image
0
Best Answer

Answer by yummy81 · Feb 03, 2018 at 05:09 PM

In Update, you loop through the Enemy array, even though not all the elements where assigned. It means that at the very begining Enemy array has only one element (foe) assigned. At that moment the NullReferenceExceptions start appearing. The Update method checks the array every frame while the coroutine fills the array at a spawnWait simultaneously resizing it. So each frame the array remains partly filled, partly empty triggering the exceptions.

To make those exceptions disappear in the console, you can add the condition in the foreach loop inside Update to skip those iterations for which there is no foe assigned:

 foreach(var foe in Enemy)
 {
     if (!foe) continue;
     foe.transform.position = Vector3.MoveTowards(foe.transform.position, Vector3.up*10, Time.deltaTime);
 }
 
 

You can also try to catch the exceptions like that:

 foreach(var foe in Enemy)
 {
     try
     {
         foe.transform.position = Vector3.MoveTowards(foe.transform.position, Vector3.up*10, Time.deltaTime);
     }
     catch {}
 }
 
 

As to "UnassignedReferenceException: The variable Prefab of Fight has not been assigned." - it seems that you didn't assign the Prefab in the Inspector. But in the code you delivered I can't see the use of the Prefab as the parameter in the Instantiate method. So I suppose that this exception appeared in the previous versions of your code.

Finally you can rewrite your code and get rid of all those arrays and use list. This is the simple example:

 public GameObject[] Foes;
 public float spawnWait;
 
 //public GameObject[] Enemy;
 public List<GameObject> Enemy;
 private int Num = 0;
 
 private void Start()
 {
     //this.Enemy = new GameObject[5];
     this.Enemy = new List<GameObject>();
     StartCoroutine(this.SpawnWaves());
 }
 
 private void Update()
 {
     foreach(var foe in this.Enemy)
     {
         foe.transform.position = Vector3.MoveTowards(foe.transform.position, Vector3.up*10, Time.deltaTime);
     }
 }
 
 private IEnumerator SpawnWaves()
 {
     while(true)
     {
         for(;;)
         {
             GameObject foe = Foes[Random.Range(0, Foes.Length)];
             this.Enemy.Add( (GameObject) Instantiate (foe) );
             /*
             // use list instead of the array
             
             this.Enemy[this.Num] = (GameObject) Instantiate (foe);
             System.Array.Resize<GameObject>(ref Enemy, Enemy.Length +1);
             this.Num++;
             */
             spawnWait=Mathf.Min(1,10/Time.time);                
             yield return new WaitForSeconds(1f);
         }
     }
 }
 
 

I do not understand why you nested one infinite the for loop inside the while loop without yielding anything and assigning only Quaternion.identity. But I suppose it's just the excerpt so I ignore that.

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 Dragonrider-Liu · Feb 04, 2018 at 03:02 AM 0
Share

$$anonymous$$any thanks!

Your if/try method solved the problem. According to your answer, I tried initiate the array Enemy[] with 0 element, array.resize before assign Prefab to it, the problem is also gone.

But I still cannot assign the instances to the array or the list directly, like Enemy[Num]=(GameObject)instantiate(foe); or this.Enemy.Add( (GameObject) Instantiate (foe) ); . With an intermediate to store the instance, both of array and list worked fine.

(For the prefab issue. "Prefab" is a GameObeject variable I used as intermediate to store the instance generated in current cycle, so that I can assign the instance to the array or list. Foe[] is assigned with the prefab in inspector. This is the way of the tutorial. It seems to provide possibility for different prefabs with GameObject[].)

Could you tell me what's the advantage of list compared to array in this issue? That I don't need to make the count, and no resize() needed?

Finally, thank you again!

avatar image yummy81 Dragonrider-Liu · Feb 04, 2018 at 08:38 AM 0
Share

Yes, the advantage of the list is that it resizes itself behind the scenes. I'm glad I could help

avatar image Dragonrider-Liu · Feb 04, 2018 at 06:53 AM 0
Share

I have got the idea. It's my fault, I added a Debug.Log() for test and forgot to change it accordingly.

Thank you for your help again!

Follow this Question

Answers Answers and Comments

182 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 avatar image

Related Questions

Error CS0177 - "GameManager does not contain a definition for 'GetPlayer' PLEASE HELP! 0 Answers

Can someone please help me find out what wrong with my code. 0 Answers

Unity {[(2D)]} RotateAround while jumping 0 Answers

My gameobject keeps leaving the screen 0 Answers

stealth Frezz when "hit&" play bttn 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