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 May 02, 2017 at 09:53 AM by MennoB for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by MennoB · May 03, 2017 at 11:42 AM · error messagenullnull reference exception

Can someone make sense out of seemingly inconsistent null reference exception?

Today I encountered the weirdest error, I hope someone can make sense out of this cause I'm baffled. I am a relative noob to Unity so please forgive and point out any wrong practices or design patterns. I have a class (below) that lets me add ammo to actors. It sends the ammo types to the component responsible for instantiating them, BeamFire and ProjectileFire; who both inherit from Fire. When I run this code, I get an error at the line Debug.Log("AddAmmoInManager" + GetFireComponent(ammoType).ToString()); because both beamFire and projectileFire are null. However, when I checked those field after initialising, in Start(), they display the correct component. What is going on here? Thanks so much for your time, this really has been frustrating me all day.

EDIT More to the point: why is beamFire and projectileFire null at line 37 when it's not at line 14? They don't seem to be destroyed externally, I say this because when the editor pauses I can still see both components on the gameobject. I call the AddAmmo from another script after Start(), and my console output is:

LeftPlayer (ProjectileFire) UnityEngine.Debug:Log(Object) ActorAmmoManager:Start() (at Assets/Scripts/Ammo/ActorAmmoManager.cs:17)

LeftPlayer (BeamFire) UnityEngine.Debug:Log(Object) ActorAmmoManager:Start() (at Assets/Scripts/Ammo/ActorAmmoManager.cs:18)

Projectile1 UnityEngine.Debug:Log(Object) ActorAmmoManager:AddAmmo(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:23) c__Iterator0:MoveNext() (at Assets/Scripts/WorldCreation/CreatePlayer.cs:60) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

Null UnityEngine.Debug:Log(Object) ActorAmmoManager:GetFireComponent(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:37) ActorAmmoManager:AddAmmo(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:24) c__Iterator0:MoveNext() (at Assets/Scripts/WorldCreation/CreatePlayer.cs:60) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

Null UnityEngine.Debug:Log(Object) ActorAmmoManager:GetFireComponent(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:38) ActorAmmoManager:AddAmmo(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:24) c__Iterator0:MoveNext() (at Assets/Scripts/WorldCreation/CreatePlayer.cs:60) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

GetFireComponentProjectile1 UnityEngine.Debug:Log(Object) ActorAmmoManager:GetFireComponent(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:39) ActorAmmoManager:AddAmmo(AmmoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:24) c__Iterator0:MoveNext() (at Assets/Scripts/WorldCreation/CreatePlayer.cs:60) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

NullReferenceException: Object reference not set to an instance of an object ActorAmmoManager.AddAmmo (AmmoType ammoType) (at Assets/Scripts/Ammo/ActorAmmoManager.cs:24) CreatePlayer+c__Iterator0.MoveNext () (at Assets/Scripts/WorldCreation/CreatePlayer.cs:60) UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 [RequireComponent (typeof (BeamFire), typeof(ProjectileFire))]
 public class ActorAmmoManager : MonoBehaviour 
 {
     private ProjectileFire projectileFire;
     private BeamFire beamFire;
 
     void Start()
     {
         projectileFire = gameObject.GetComponent<ProjectileFire> ();
         beamFire = gameObject.GetComponent<BeamFire> ();
 
         Debug.Log (projectileFire);
         Debug.Log (beamFire);
     }
 
     public void AddAmmo(AmmoType ammoType)
     {
         Debug.Log (ammoType);
         Debug.Log("AddAmmoInManager" + GetFireComponent(ammoType).ToString());
 
         GetFireComponent(ammoType).AddAmmo (ammoType);
     }
 
     public void RemoveAmmo(AmmoType ammoType)
     {
             Debug.Log ("RemoveAmmo");
         GetFireComponent (ammoType).RemoveAmmo (ammoType);
     }
 
     private Fire GetFireComponent(AmmoType ammoType)
     {
         Debug.Log (projectileFire);
         Debug.Log (beamFire);
         Debug.Log ("GetFireComponent" + ammoType);
 
         if (AmmoData.IsProjectile (ammoType))
             return projectileFire;
         if (AmmoData.IsBeam (ammoType))
             return beamFire;
         
         Debug.Log ("Error: ammoType is unknown");
         Debug.Break ();
         return null;
     }
 }
 

EDIT Thanks a lot to everybody helping me. It's really, really appreciated and makes for a very positive first experience on this site.

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

3 Replies

  • Sort: 
avatar image
1
Best Answer

Answer by Matthewj866 · Apr 25, 2017 at 03:57 PM

Hi there.

I can't cay for certain, but based on what you've said about projectileFire and beamFire becoming null suggests something externally is destroying them, however I can't be certain of that, so I will just go with my own theory.

AmmoData.IsProjectile() and AmmoData.IsBeam() are both returning false because the ammoType in question has been either set up incorrectly, or the way the check is being done has issues of it's own - again, an external problem. This means it will return null because that's what you've told it to do. It cannot call ToString() on null, because null literally means nothing.

Hope this helps.

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 MennoB · Apr 26, 2017 at 12:25 PM 0
Share

Hi, thanks so much for helping me out! I double checked, the IsProjectile and IsBeam functions are sound; also the error at lines 45 - 46 is never reached which means one of my functions must be returning true (right?). For sure the ToString method is passed a null parameter, and as you said my best guess is something externally is destroying them, but this doesn't seem to be happening.

avatar image Matthewj866 MennoB · Apr 28, 2017 at 02:57 PM 1
Share

Unfortunately I think I'd need to get a bit more hands on to find out for myself, but another possibility is that somehow the object is pointing to the saved prefab rather than the in-world instance? Which would of course make it return null, but besides that based on the information given I'm kind of stumped. :s

avatar image MennoB Matthewj866 · May 02, 2017 at 09:46 AM 0
Share

You are right! I read your answer but somehow first looked into the one from Bunny83. As I was copying the code to use in the comment on his answer, I noticed the error you suggested:

StartCoroutine(AddAmmo (leftPlayerPrefab, leftPlayerStartAmmo));

As you can see I'm adding ammo to the prefab ins$$anonymous$$d of the instance, just like you said. I'm gonna leave the bad code up for posterity. This code works like a charm:

StartCoroutine(AddAmmo (leftPlayer, leftPlayerStartAmmo));

Thanks so much!

avatar image
1

Answer by krisuman · Apr 25, 2017 at 03:52 PM

What is AmmoData.IsProjectile and AmmoData.IsBeam doing? (Line 40 and 42) Are you sure that at least one of them returns true? Becaouse it looks that your function GetFireComponent returns null and that's why you got null reference exeception.

Comment
Add comment · Show 1 · 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 MennoB · Apr 26, 2017 at 12:19 PM 0
Share

Hey, thanks so much for your help. You're completely right; unfortunately I didn't make myself as clear as I could. Indeed they return null; my problem is: how did they become null? As far as I can tell I'm not changing them. Not in this script; and also not in any other script: the BeamFire and ProjectileFire are are still there on the gameobject when the editor pauses on the null reference exception.

avatar image
1

Answer by Bunny83 · Apr 28, 2017 at 03:47 PM

Well, it seems that your "GetFireComponent" is called from another component. You most likely have a "race condition" here (not related to threads in this case ^^). You initialize your two variables inside Start. However your other component that calls "GetFireComponent" directly or indirectly seems to run before your Start runs.

The easiest solution is to renamce "Start" into "Awake". Awake is called when the object has been created / loaded / instantiated. Start is called "later" right before Update is called on the scripts.

If you want to keep the code in Start you have to make sure that scripts runs before the other. You can do this by changing the script execution order. Note that if the other component tries to access GetFireComponent from it's own Awake method the script execution order won't help as Awake is always called before Start.

Have a look at the flowchart over here for more information.

Comment
Add comment · Show 1 · 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 MennoB · May 02, 2017 at 09:25 AM 0
Share

Hey, thanks so much for your answer! I wasn't aware of the term "race condition" nor the ability to change the execution order, so I'm very grateful for this new knowledge. However I fail to see how it applies here. I tried your suggestion of rena$$anonymous$$g the Start method to Awake, but the same error arose. Also, lines 17 and 18 return the correct component. To prevent this type of error altogether I had also called AddAmmo from a "LateStart", a method recommended here: http://50.17.205.126/questions/971957/how-to-initialize-after-start.html?childToView=972003#answer-972003 . I've included the calling script but I had problems getting it into the right format for some reason.

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

public class CreatePlayer : $$anonymous$$onoBehaviour { public GameObject leftPlayerPrefab; public GameObject rightPlayerPrefab; public ShipType leftPlayerShipType; public ShipType rightPlayerShipType; public AmmoType[] leftPlayerStartAmmo; public AmmoType[] rightPlayerStartAmmo; public Vector2 leftPlayerPos; public Vector2 rightPlayerPos;

 private ShipCreator shipCreator;
 private Player$$anonymous$$iddle player$$anonymous$$iddle;

 void Start()
 {
     shipCreator = GameObject.Find ("ShipHolder").GetComponent<ShipCreator> ();

     CreateLeftPlayer ();
 }

 private void CreateLeftPlayer()
 {
     GameObject leftPlayer = GameObject.Instantiate (leftPlayerPrefab, transform);

     shipCreator.CreateShip (leftPlayerShipType, leftPlayerPos, leftPlayer.transform);

     leftPlayer.name = "LeftPlayer";

     StartCoroutine(AddAmmo (leftPlayerPrefab, leftPlayerStartAmmo));
 }

 IEnumerator AddAmmo (GameObject player, AmmoType[] ammoTypes)
 {
     yield return 2;

     foreach (AmmoType ammoType in ammoTypes)
         player.GetComponent<ActorAmmo$$anonymous$$anager> ().AddAmmo (ammoType);    
 }

}

Edit This code contains the error pointed out in the accepted answer; see above for the correct version.

Follow this Question

Answers Answers and Comments

102 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

Related Questions

is my enemy selector null reference a problem? 1 Answer

Having issues with a NullReferenceException error. Code does as expected in some instances but I receive the error in others. Debugger directs me to line where if(hit.collider.tag == (DestructibleCube")). 1 Answer

GameObject only spawning 60% of the time (c#) 1 Answer

nullreferenceexception object reference not set to an instance of an object 2 Answers

ArgumentNullException: Value cannot be null. parameter name: Source 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