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 /
This question was closed Jul 25, 2018 at 05:16 PM by Igor_Vasiak for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Igor_Vasiak · Jul 25, 2018 at 02:18 PM · scripting problemnullreferenceexceptionscriptableobjectreferencingscriptable object

ScriptableObject reference resetted after a method is finished.


Context


This is for an Inventory System, and I'm trying to make items the more automatically-ish way possible.


This is an issue regarding Weapons spawning bullets. Sort of.


Let's say I have a ScriptableObject called ItemData. It is a pretty generic ScriptableObject, one that holds only data.


Now, let's say that I have it assigned to a Script called Item. Also, let's say that I have another ScriptableObject assigned as one of the various ItemData's fields. This one is called MWActions. It is a slightly more complex SO, containing not only data, but Methods as well. It inherits another SO which is called WeaponActions, which inherits Actions which inherits ScriptableObject.


Now, as needed, I have yet another ScriptableObject assigned to this MWAction one. Lets call it... ProjectileData.


Just to recap, this "assigned var on assigned var" goes like this:


ProjectileData is assigned to MWActions which is assigned to ItemData, which finally is assigned to Item, the caller MonoBehaviour.


I also have a Script on my player that is used as an intermediate between the visual part of the items (i.e. being displayed on the player's hand, or the position of the bullets depending on each item). Lets call it CharacterInventory.


Issue


Now, I'm trying to pass the reference of the ProjectileData to the CharacterInventory from the MWAction ScriptableObject.


The player selects the weapon and clicks to fire. The MWAction "assigns" (or sets) the projectileData variable inside CharacterInventory and spawns a bullet.


The bullet was supposed to get that ProjectileData and use it, but unfortunatelly that won't happen. The projectileData var is null by then.


The issue is, after this "assignment" method finishes running, the reference on that other Script becomes null. Now, why is this even a thing? Is it a bug?


Some Notes


The reference on the other script keeps true to the PData passed to it until the method finishes. It only gets null after that.


The assignment isn't the only thing happenning on that method, but nothing breaks the reference to the PData.


That crazy inheritance above is needed because I'm trying to make use of the very flexible Polymorphism Serialization that Scriptable Objects have. I've already tried with MonoBehaviours, but... No success.

Comment
Add comment · Show 7
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 Harinezumi · Jul 25, 2018 at 03:05 PM 0
Share

Could you share some code? It is clear what the problem is, but it is a hard to reason about it and find the actual cause without seeing what you actually do.

avatar image Igor_Vasiak Harinezumi · Jul 25, 2018 at 03:16 PM 0
Share

Well, I can't share the code, but I can try to give a better insight on what I'm doing.

avatar image MacDx · Jul 25, 2018 at 04:50 PM 0
Share

Here are some questions to get a bit more insight:


Did you change the hideFlags property on any of these scriptable objects?


Are you creating all these scriptable objects at runtime or do they already exist before running the scene (created through asset menu)?


When did the problem start? I'm thinking you didn't create this whole structure of chained scriptable objects from the get go and then tested it after to find this problem, maybe you had a different way of doing this before settling on the current architecture. If so, how's the current code structure different from the point where things "worked"?

avatar image Igor_Vasiak MacDx · Jul 25, 2018 at 05:00 PM 0
Share

1 - No, I didn't.

2 - They already exist.

3 - Eh... The code that worked before doesn't exist. This is the first iteration.

avatar image ShadyProductions · Jul 25, 2018 at 04:58 PM 2
Share

Problem is solved, I $$anonymous$$mviewed with him.

avatar image MacDx ShadyProductions · Jul 25, 2018 at 05:02 PM 0
Share

Nice!

I'm curious now, what was the issue? (If you can share of course)

avatar image Igor_Vasiak MacDx · Jul 25, 2018 at 05:09 PM 1
Share

Posted it.

2 Replies

  • Sort: 
avatar image
1
Best Answer

Answer by Igor_Vasiak · Jul 25, 2018 at 05:09 PM

Okay, found it! As @ShadyProductions stated while helping me with this issue, lazy loading creates its own variables when working with ScriptableObjects, so I was creating a totally new CharacterInventory while doing the whole process, and assigned the ProjectileData to it.


Lazy loading may look like this¹, for those ones who doesn't know:


 private MyClass _myVar;
 public MyClass MyVar => _myVar ?? (_myVar = //Get the component);


And I was using it. So, just a tip, avoid lazy loading on ScriptableObjects, okay?


Thanks for everyone who took their time to try to help me.


¹Lazy loading structures may vary depending on what you'd do. The one above is just an example, but Lazy loaded variables are, in general, getter Properties initialized only when called by something. They return a cached value if not null or cache the value needed and return it.

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
1

Answer by Bunny83 · Jul 25, 2018 at 02:44 PM

ScriptableObject, just like any other UnityEngine.Object derived type, has its roots in the native c++ engine core. Those objects are not garbage collected but have to be destroyed explicitly using Destroy (DestroyImmediate in the editor). Also "some" of them can not be created with "new". This applies mainly to Components (which include MonoBehaviours as well) and ScriptableObjects. Components can only be created with AddComponent, ScriptableObjects with CreateObject().


Now since objects derived from UnityEngine.Object actually have a native code counterpart, this native instance need to be explicitly destroyed if you want to get rid of it. Some things might get destroyed when you load a new scene is the object belonged to the old scene. Generally when the native part of a UnityEngine.Object is destroyed or just missing for some reason (you created it with new) the managed instance will become a fake null object. Since managed objects can't be explicitly destroyed the managed part just fakes that it is null because it's native part is missing. Fot that Unity has overloaded the == operator of UnityEngine.Object to catch this case.


If a reference to such an object suddenly turns "null" or appears to be null it most likely got destroyed.


Before you scream "BUG" you may want to create a minimal reproduction case and share it here. If you can't reproduce this issue in an isolated case it just means your either not very good at debugging your code or your code is not structured enough (Spaghetti code? Big ball of mud? or some other anti pattern?)


You have presented this problem in a very abstract fashion. So there's no way for us to actually follow what is happening and fully understand where the issue might come from.

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 Igor_Vasiak · Jul 25, 2018 at 03:15 PM 1
Share

No, no Spaghetti code, Bunny! I'll try to give you more information regarding what you stated on your answer.


Also "some" of them can not be created with "new


Yeah... I'm not creating or instantiating any ScriptableObjects like that.


Some things might get destroyed when you load a new scene is the object belonged to the old scene.


Nope, not reloading or loading scenes. All the testing was done on the same scene.


Generally when the native part of a UnityEngine.Object is destroyed or just missing for some reason (you created it with new) the managed instance will become a fake null object.


No Destroy() is being called anywhere in the game, so I'm pretty sure I'm not destroying my ScriptableObject. I'm just passing a reference, man!


If you can't reproduce this issue in an isolated case it just means your either not very good at debugging your code or your code is not structured enough.


That actually hurts... XD


Hopefully that helps you on helping me.

Follow this Question

Answers Answers and Comments

160 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

Related Questions

Giving a ScriptableObject asset reference to all instances of a MonoBehavior? 0 Answers

Scriptable Object is getting set to null 0 Answers

NullReference on trying to instantiate a prefab which has been set using scriptable object,Particle giving null reference but works in scene view 0 Answers

Show on ScriptableObject all other ScriptableObjects that reference it 0 Answers

Duplicating Component with Some Scene References in Serialized Scriptable Object Class Reference 0 Answers


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