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 /
avatar image
1
Question by Deadcow_ · Jan 05, 2016 at 03:31 PM · nullreferenceexceptioneventeventsexecution orderondestroy

Unsubscribe events in OnDisable causes NullReferenceException

My approach is quite simple. GameManager got static references to my sub systems like AudioManager, InterfaceManager, SavegameManager etc (managers are not destroyed between scenes) . Components on scene may subscribe to this managers events, like in this sample with ItemsManager event:

 private void OnEnable()
 {
     GameManager.Items.OnInventoryItemChanged += OnAmountChange;
 }
 private void OnDisable()
 {
     GameManager.Items.OnInventoryItemChanged -= OnAmountChange;
 }

This static properties cached on GameManager Awake (and GM is first in script execution order) and if variable is null - try to find it on scene (to find reference if I'll need this manager in Editor script, for instance.

This approach causes a bunch of NullReferenceExceptions when I stop the game in the editor. Apparently it happens because some of my managers destroyed before this OnDisable called.

By the way, all my managers is placed on the same Object: alt text

Maybe there is a way to force this object to be destroyed at the end, when all other objects on scene is destroyed? Will script execution order affect destroy order?

2016-01-05-18-14-46-unity-personal-64bit-002-roadu.png (5.1 kB)
Comment
Add comment · Show 4
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 Denvery · Jan 05, 2016 at 07:44 PM 0
Share

In your example, what is null - Game$$anonymous$$anager or Items?

avatar image Deadcow_ Denvery · Jan 05, 2016 at 08:09 PM 0
Share

Items. I receive this null exception time to time from different systems linked with Game$$anonymous$$anager, but newer from Game$$anonymous$$anager itself. $$anonymous$$ay be it's just random luck and one day Game$$anonymous$$anager will be destroyed first

avatar image Denvery Deadcow_ · Jan 05, 2016 at 08:11 PM 0
Share

Try to unsubscribe in OnDestroy ins$$anonymous$$d of OnDisable...

avatar image Dave-Carlile · Jan 05, 2016 at 08:12 PM 0
Share

You can have your script run last using the Script Execution Order settings. Not completely sure if that will solve your issue.

2 Replies

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

Answer by Deadcow_ · Jan 06, 2016 at 09:20 AM

Okay, I find workaround for this specific issue:

 private void OnApplicationQuit()
 {
     MonoBehaviour[] scripts = FindObjectsOfType<MonoBehaviour>();
     foreach (MonoBehaviour script in scripts)
         script.enabled = false;
 }

When OnDisable called - nothing is destroyed yet.

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

Answer by LordDarkon76 · Jan 05, 2016 at 09:21 PM

Sometimes the manager is destroyed before listener.

 if(GameManager.Items != null)
 {
        GameManager.Items.OnInventoryItemChanged -= OnAmountChange;
 }

Adding that protection will solve your problem.

Comment
Add comment · Show 4 · 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 Dave-Carlile · Jan 05, 2016 at 09:32 PM 0
Share

An object reference doesn't automatically get set to null when the object is destroyed.

avatar image LordDarkon76 Dave-Carlile · Jan 05, 2016 at 11:06 PM 0
Share

You made my doubt, after checking my project I use.

  if(Game$$anonymous$$anager.Items)
  {
         Game$$anonymous$$anager.Items.OnInventoryItemChanged -= OnAmountChange;
  }
avatar image Bunny83 Dave-Carlile · Jan 05, 2016 at 11:12 PM 2
Share

Well, for UnityEngine.Object references it does thanks to Unity's fake null objects. It's actually a nice feature. You can even check if a script itself has been destroyed like this:

 if (this == null)

This would be complete nonsense in normal C#, but with UnityEngine.Object references it's possible. An object becomes fake null when it has been destroyed. The managed part lives on until all references are gone. Until then you can still use the instance to some degree but a null check will return true.

avatar image Deadcow_ · Jan 06, 2016 at 09:09 AM 0
Share

This looks like a dirty way to solve this problem. I want to ensure, that my managers are always available, even if not in playmode.

Game$$anonymous$$anager check for null itself, and if Items is null and not in scene = throw custom exception "Items$$anonymous$$anager not found on scene", so in my case any call of Items will cause exception, even "Game$$anonymous$$anager.Items != null"

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

37 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

Related Questions

Make prefab that generated more than once listener in Unity Events 0 Answers

Check if a listener has already been added to a button? 2 Answers

One listener for multiple objects? 2 Answers

Setting up EventTrigger programmatically for GameObject throws NullReferenceException 0 Answers

Unity accepts default parameter in event subscription but fails 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