Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by vexe · Jun 06, 2013 at 04:01 PM · c#nullreferenceexceptionvirtualoverride

A NullReferenceException even though I'm sure that object was assigned?

OK - I've been following the Stealth game project example - didn't really like the way the guy's been organizing the code - so I thought I could do better - so basically, what I have is:

1- a game object called 'gameController' (much like in the tuts) that has: A) a script attached to it called "GameControllerScript" B) a number of child objects (you don't have to know about all of them) - one of them is "music"

2- now 'music' has: A) a script attached to it called "MusicScript" B) two child objects: NormalMusic, PanicMusic each with NormalMusicScript and PanicMusicScript attached to respectively.

Logically, I made NormalMusicScript and PanicMusicScript inherit from MusicScript, here's my codes:

 public class Music : MonoBehaviour {
  
     public float maxVolume = .8f;
     public float minVolume = .1f;
     public float fadeSpeed = 2f;
     protected GameControllerScript gameController;
     protected float targetVolume;
  
     public virtual void Awake()
     {
         gameController = transform.parent.gameObject.GetComponent<GameControllerScript>();
     }
     public void FadeTo(float volume)
     {
         audio.volume = Mathf.Lerp(audio.volume, volume, fadeSpeed * Time.deltaTime);
     }
 }


 public class PanicMusicScript : Music {
  
     void Update()
     {
         if (gameController.PlayerHasBeenSpotted())
         {
             targetVolume = maxVolume;
         }
         else
         {
             targetVolume = 0;
         }
         FadeTo(targetVolume);
     }
 }


(The NormalMusicScript has similar code so no need to post it)

Now the problem is: when I run the game, I get a NullReferenceException at the line

 if (gameController.PlayerHasBeenSpotted())

saying that gameController is null - So I debugged to check the problem - I put a breakpoint at the assignment of gameController in the Awake of MusicScript parent class - it got assigned no problem - but then after I stepped, the same Awake of the parent got executed again! - but this time, gameController returned null! - I didn't know what that was about - so I thought that if I didn't override the Awake in the child, the Awake of the parent will also get called on the child - so I tried this:

 public override void Awake()
 {
     return;
 }

When I debugged again - it didn't execute Awake twice - but still broke at the same line saying that gameController is null I tried to use the constructor instead of Awake (cuz I remember having similar problem in the past and managed to solve it that way) but no luck - got some other errors saying not to use the constructor or something... I also tried to initialize in Start instead of Awake - same.

Why is this happening? - any help would be appreciated - thanks a lot in advance.

Comment
Add comment · Show 10
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 Julien-Lynge · Jun 06, 2013 at 04:03 PM 0
Share

Are you certain the same $$anonymous$$onoBehaviour is being executed twice? Can you try logging the name of the transform in the awake function? Then try logging the name of the transform.parent.

avatar image vexe · Jun 06, 2013 at 04:13 PM 0
Share

O$$anonymous$$ - that's pretty much weird. In the parent $$anonymous$$usicScript class, I logged its transform - I checked out the address, first time it was something like 0x146b38 - As expected - awake got executed again but this time the log gave something else - as if there's 2 'music' objects with $$anonymous$$usicScripts! - I also logged the parent's transform the child's Awake, guess what? - it was 0x146b38 and it only got executed once - so the issue's in the 'music' game object somehow :/

avatar image vexe · Jun 06, 2013 at 04:37 PM 0
Share

It's as if Unity is telling us not to use inheritance and OOP? :( what's the better approach then? - I'm confused.

avatar image Julien-Lynge · Jun 06, 2013 at 04:50 PM 1
Share

I'm not sure whether or not the issue is with inheritance. I've certainly never seen anything like what you're describing, so I do wonder if there's something weird in your project.

As with all debugging, it all comes down to narrowing where the issue lies :) Are your two classes defined in separate script files? Having two $$anonymous$$onoBehaviour-derived classes in a single script could definitely be confusing to Unity.

What happens if you start a new project, add the two classes you have defined here, attach Pan$$anonymous$$usicScript to a single GameObject, and hit play?

avatar image Julien-Lynge · Jun 06, 2013 at 06:02 PM 1
Share

Transform is a component, and GameObject is the container that holds components.

'transform' is just shorthand for GetComponent(); All GameObjects have to have a transform component, so you're guaranteed that transform will never return null.

So transform.parent.gameobject is: "get the transform component, get its parent transform component, get the gameObject container for that transform component."

Note that GameObject itself doesn't store parenting information ( it's just a container) - the parenting is stored in the transform. So your second example wouldn't compile. You could do "transform.parent.gameObject.transform.parent", but that would be redundant :)

Since parent is of type transform, you can certainly do things like transform.parent.parent.parent....

Show more comments

1 Reply

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

Answer by Julien-Lynge · Jun 06, 2013 at 05:51 PM

correct - transform always means the transform of the script it's being called from. So you could have a bunch of different PanicMusic scripts, and each would have a different transform (assuming they're all attached to different game objects).

In OOP, remember that there is no connection between instances of objects, even if they share similar class traits. There is no connection between your MusicScript and you PanicMusicScript instances within Unity either.

So to clarify, in the setup you have above, the parent of MusicScript's transform (e.g. music) is game controller, and the parent of PanicMusicScript's transform (e.g. PanicMusic) is music.

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

16 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

Related Questions

How to call child overide function? 1 Answer

Multiple Cars not working 1 Answer

Javascript Inheritance; how to not override functions? 1 Answer

Distribute terrain in zones 3 Answers

Function GUI with a Return value 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