Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question SerializeField displays null in editor, but is not

Discussion in 'Editor & General Support' started by DTECTOR, May 14, 2023.

  1. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    What are the reasons why a serializefield would always show null? I have a field that is always null, while I can access and use the field throughout the game and it is clearly not null.
     
  2. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    Are you sure you're looking at the correct GameObject?
     
  3. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    Hmm, it's a singleton, so I think so.
     
  4. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    There's so many intricacies to Unity I find myself forgetting and remembering things all the time. It was a class that would not show in the editor. I made UnityEngine.Object it's base class so then it was showing as a serializefield in the editor. But it will not change from null after being passed an object of that type/initialized with an object of that type.
     
  5. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    I don't believe I've ever seen this behavior before.
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    Being a singleton doesn't mean you haven't accidentally added it to multiple game objects.

    You can't just inherit from
    UnityEngine.Object
    . You either inherit from Monobehaviour to be able to attach it as a component, or ScriptableObject to make instances of it in your project files.

    Show some code, show some screenshots, and maybe we can explain your misunderstanding here.

    Are you getting confused with it not drawing in the inspector and thinking it's null?
     
  7. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    I'm using reflection to ensure there is only 1 instance in the scene, so no there's only one. And all the logic is within it's own self so it would not make sense for it not to work. It should work on any instance regardless. I am not sure what you are asking. There is no confusion, as stated in the original post, it's not null, but the editor does not update and continues to display it's value as null but it's not null and I've stepped through it with debugger and tested code that interacts with the property, there's nothing wrong with it and the values get read and passed without any issues.

    As for UnityEngine.Object, yes you can inherit from it, and it clearly states it's purpose in the docs, it is the unity equivalent of System.Object for .Net extended with Unity Editor and Engine compatibility. The small set of features it gives to other classes like monobehavior are all I need. I used it to achieve serialization within the editor. And it did just that. I don't need a transform or a component and it's a runtime only object that results from various data elements from scriptable objects processed through various game related functions. I can't imagine how to show all the moving parts as it's a lot of code and files.

    I was hoping someone had experience with disparities between the object in memory and the state being displayed in the editor. If not that's alright, it's a pretty complex object so maybe I am doing too much with it for unity to serialize properly. I only wanted to serializefield for visual feedback during testing. I guess I will have to go without.

    Thank you guys for the suggestions.
     
  8. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    It would not matter because the logic that assigns the value is all self contained within the class. So in the editor, any and all of the respective gameobjects with the component would reflect the same changes.
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    Are you trying to serialise/display a static field???
     
  10. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    This is where your problem is coming from, most likely. While you can inherit from UnityEngine.Object, it is not the Unity equivalent of System.Object, and should not be used in this way. UnityEngine.Object represents the C# wrapper around objects that exist within Unity's C++ backend. The reason it's staying "null" in the editor is probably because Unity detects that it is a UnityEngine.Object and so draws an object field for it, but otherwise has no knowledge of how to serialize it for use in the editor. And you can't give Unity that knowledge because the C++ portion is closed source, and they already gave us utilities for arbitrarily serialized classes in the form of ScriptableObjects/MonoBehaviours.

    In short, you cannot create your own custom UnityEngine.Object classes. I don't know what you read in the docs that gave you the impression it should be used like System.Object, but that is not the case. If you want to display a singleton in the inspector, your best bet is to inherit it from ScriptableObject.

    Well... it didn't, because it's showing as "null". You can access the fields during runtime because the instantiated object exists. That doesn't mean its serialized representation exists.
     
    spiney199 likes this.
  11. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    What you are saying may be correct, I would not be able to confirm as I don't see that anywhere in the docs, why do the docs say this about the object class? - "Unity has a class in the UnityEngine namespace called Object, which acts as a base class for all objects that Unity can reference in the editor. Classes which inherit from UnityEngine.Object have special functionality which means they can be dragged and dropped into fields in the Inspector
    , or picked using the Object Picker next to an Object field.
    "

    https://docs.unity3d.com/Manual/class-Object.html

    If you have a source that you are getting this information from, could you share it with me? I would like to better understand the engine.
     
  12. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    The way the docs are written certainly seem to indicate this is possible, but I am pretty sure this is just bad docs writing. This question displays a simpler example of the same problem that you ran into: https://answers.unity.com/questions/646661/is-there-a-reason-not-to-inherit-from-unityengineo.html. The answer also describes in more detail the trouble with inheriting from UnityEngine.Object.

    You can see that an object that inherits from UnityEngine.Object is always in a phantom "null" state.
     
  13. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    None of that in the docs actually means you can or should be inheriting from the class. As end users we only get access to
    Monobehaviour
    and
    ScriptableObject
    to create our own assets, and they've been set up exactly for that purpose.

    Other Unity provided classes, some of which inherit directly from classes like
    UnityEngine.Object
    ,
    Component
    , or
    Behaviour
    , are doing internal stuff to manage their marshalling, serialisation, etc, and most importantly, the generation of the C++ partner object. Most all these assets have specific methods for creating them too, such as GameObject's constructor, and
    Sprite.Create
    's factory method.

    In that same vein, we also can only add components via
    AddComponent
    and can only generate scriptable objects via
    ScriptableObject.Instantiate<T>
    . Doing so any other way bypasses the generation of the C++ object.
     
  14. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    Thank you, so I should just not even bother with this since I don't want any of the stuff on the scriptableobject class nor the monobehavior class. Because implementing a custom editor for this is not worth it for me in this case.
     
  15. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    Do you have a reference to a source mentioning the C++ partner objects and other stuff you mention? I don't get any search results for this. Or are these intuitive assumptions from your experience with C++ and C# interop?
     
  16. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    It's just from my experience working with the engine and coming across various bits of information, such as some of the Unite talks and here on the forums. I wouldn't have a direct source but the information is definitely out there.

    A lot of Unity's C# classes like GameObject and Transform are nothing but wrapper classes that are there to interface with the internal C++ object. If you peek into the code with Visual Studio or other tools you'll see it's nothing but external calls. They C# objects hold no information themselves.

    This is also why we have to purposefully destroy Unity objects, to ensure the managed memory taken by the C++ is freed as well. Otherwise they hang around in memory forever.
     
  17. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    What "stuff" does the ScriptableObject/MonoBehaviour classes have that you don't want?
     
    spiney199 likes this.
  18. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    All of it. I am creating a class at runtime by processing the data of a few different scriptableobject types and the result is a bunch of floats influenced by a bunch of properties of the game that generally increase overtime during gameplay in various manners. I don't want anything else in there. I've also began to avoid the scriptableobject like the plague now that it serializes any changes at runtime. All it takes is mistakenly leaving out an Instantiate call when loading a scriptableobject and suddenly you have permanently overwritten the data on some base data class meant to be referenced for base data of the game world. Which can cause permanent unexpectected behavior because the values are all way off. And that might be manageable in a low volume data environment but if you have to manage and maintain 400-1000 different configurations that may go through 1000s of value manipulations in a single hour its just not feasible. So I can ensure I don't make that mistake by using a runtime instantiated class, which would not use any of the stuff on scriptableobject and would merely serve as a field/property of another monobehavior script.
     
    Last edited: May 22, 2023
  19. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    I understand the desire to avoid having to clone a ScriptableObject, but ScriptableObjects are able to be created at runtime just fine:

    Code (CSharp):
    1. public class MyScriptableObject : ScriptableObject {
    2.   public float value = 3f;
    3. }
    4.  
    5. // elsewhere
    6. var myObj = new MyScriptableObject();
    7. Debug.Log( myObj.value ); // 3.0
    Alternatively, does it fit your requirements to make your data class serializable and set it to a serializable field via
    [SerializeReference]
    for display in the editor?
     
    Last edited: May 22, 2023
    DTECTOR likes this.
  20. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    FYI Scriptable objects should only be created with
    ScriptableObject.CreateInstance<T>
    .

    That aside I don't see the point of instancing scriptable objects at runtime. Based on OP's use case a plain C# class is probably a good fit here.

    Still no idea what they're going about with the initial premise of this thread, mind you.
     
  21. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    I see that emits a warning now. Good to know.
     
  22. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,907
    Maybe I'm mistaken, but reading this thread I got the impression we only talk about serialization? To be able to show something in the inspector?
    Because if this is the case, just drop everything and make a simple
    [Serializable]
    class without inheriting from Unity classes and get on with it. If you don't want to attach to a game object, but only put it in another
    MonoBehaviour
    , it is all you need.
     
    DTECTOR likes this.
  23. DTECTOR

    DTECTOR

    Joined:
    Aug 23, 2020
    Posts:
    128
    Yeah I gave up on my pursuit to fight the system and just used serializable attribute.
     
    Madgvox likes this.