- Home /
Save Unity.Object as an asset
Hi guys,
I am trying to use AssetDatabase.CreateAsset
to save some custom made data (grid in this example). I know that in order to use CreateAsset
, I need to pass an Unity.Object
instance. So I create a specific class that inherits from Unity.Object
and have just one field that holds my data.
public class GridSaveObject : UnityEngine.Object
{
public GridMapData gridMapData;
public GridSaveObject(GridMapData gridMapData)
{
this.gridMapData = gridMapData;
}
}
Now, inside the custom inspector (in Editor mode only, but I don't think that is the problem here), I make a call:
var obj = new GridSaveObject(new GridMapData());
Debug.Log(obj== null); // returns true
I don't even see the reason to mention anything that goes after that, cause what's the point. The question, how does one create an instance of such objects? I know it is possible, cause the unity way of creating Materials is the same var mat = new Material (some_link_to_shader);
One way that I could fix that was to go ScriptableObject
, and it fixed the problem, but for me it is a question of general understanding of the principle I guess
Answer by Namey5 · Jan 16, 2021 at 03:08 AM
Unity Objects aren't generally supposed to be inherited from directly and also have some weird quirks that you would be experiencing here. 'Object == null' doesn't do what you are probably expecting - in order to guarantee safety with Unity's object instancing systems, Unity overloads the '==' operator for objects such that they do additional checks against the scene rather than just checking if the object pointer is valid. In the case of a GameObject this would work because the GameObject() constructor automatically adds it to the scene and initialises it, however because Object is just a generic base class that isn't the case and therefore you would need to handle it manually. This exact use case is actually shown as an example in the docs at the bottom of the 'Object.operator ==' page;
https://docs.unity3d.com/ScriptReference/Object-operator_eq.html
ScriptableObject inherits from UnityEngine.Object and is designed pretty specifically for this case; serializing an object to a Unity asset. ScriptableObjects should be created via the CreateInstance method, so I've added a static function to work in the same way your constructor would above.
[System.Serializable]
public class GridSaveObject : ScriptableObject
{
public GridMapData gridMapData;
public static GridSaveObject NewInstance(GridMapData gridMapData)
{
GridSaveObject instance = ScriptableObject.CreateInstance<GridSaveObject>();
instance.gridMapData = gridMapData;
return instance;
}
}
...
GridSaveObject obj = GridSaveObject.NewInstance (new GridMapData ());
AssetDatabase.CreateAsset (obj, "GridObject.asset");
I would also make sure to mark your GridMapData class as [Serializable] if you want it to work properly with the Unity Editor/serializer.
Your answer
Follow this Question
Related Questions
Moving and manipulating object trought scenes in Unity 4 0 Answers
NullReferenceException: Object reference not set to an instance of an object ? 1 Answer
How do I restrict game to only instantiate 1 instance of object? 1 Answer
NullReferenceException:"Object reference not set to an instance object" 1 Answer
Object reference not set to an instance of an object 0 Answers