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.
Are you sure you’re looking at the correct GameObject?
Hmm, it’s a singleton, so I think so.
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.
I don’t believe I’ve ever seen this behavior before.
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?
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.
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.
Are you trying to serialise/display a static field???
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.
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.
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: Is there a reason not to inherit from UnityEngine.Object if I wanted the basic functionalities that UE.Object gives? - Questions & Answers - Unity Discussions. 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.
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.
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.
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?
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.
What “stuff” does the ScriptableObject/MonoBehaviour classes have that you don’t want?
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.
I understand the desire to avoid having to clone a ScriptableObject, but ScriptableObjects are able to be created at runtime just fine:
public class MyScriptableObject : ScriptableObject {
public float value = 3f;
}
// elsewhere
var myObj = new MyScriptableObject();
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?
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.