I have a MonoBehaviour class that has data in it like:
public class C : MonoBehavior
{
public GameObject referenceToOtherPrefab;
public A[] myAList;
}
// C# class "A"
public class A : ScriptableObject
{
public MyEnum someEnumVal;
public GameObject[] otherPrefabs;
public C myRefToOwnerC;
}
Anytime I create a GameObject prefab with a C component on it I can edit the data just fine with a custom editor class. The Editor class for C manages allocating the A instances with ScriptableObject.CreateInstance() and allocating the arrays.
Yet whenever I run the game or close and re-open the editor these PREFAB objects get their data wiped. Not the scene versions the prefab versions just lose their data.
Whats weird is that even the referenceToOtherPrefab member gets lost and that is just a simple GameObject reference to a prefab that I have used successfully in many other examples. Its as if there is something simple I am overlooking that is preventing the C class from being serialized in any way shape or form.
To clarify, the data that is being reset is not the ones within any scene instance or run-time instance. It is the prefab instances.
ScriptableObject is not serialized in the current scene. They have to be stored in an asset manually (AssetDatabase). In your case it seems that it would make more sense to use just a serializable cursom class. It’s not the MonoBehaviour that is losing it’s data, it’s the ScriptableObject which simply doesn’t exist after a restart if you haven’t saved it somewhere.
We had similar question a couple of times. See this one for example:
Unless you’re interested in writing an editor for your class you should stay away from ScriptableObject at least when you want it to be serialized.
If you declare your class like this:
[System.Serializable]
public class A
{
// [...]
it will probably behave like you want.
Yeah actually I originally wrote it that way and when I started experiencing this problem I tried re-writing it as a ScriptableObject thinking that the serialization would be handled. Sounds like something else is still afoot here yet undetermined. I will revert back to what I had but that doesn't help either.
The cross referencing here may be my issue but I would not expect it to lose everything but rather only that assignment. I will try it without that too and see if that makes a difference. If I were to make such a connection where the link from A to C was private or protected that should resolve as well I would think? Can you explain what you mean by "User Prefab" vs "Model Prefab" The prefabs I have been working with are always just an empty game object where I add script components or child GameObjects within it. Specifically what is your distinction between "User" and "Model"?
Ok as an update I tried removing my custom editor class and letting the default editing widgets do their thing and now it does save the data and restore the data correctly. So something may be wrong with the way I setup my custom editor but it is the same as I have done for other classes that do work.
Thanks for your tips Bunny83. Just to clarify though: "Headsup note: if you put one element in a list (or array) twice, when the list gets serialized, you'll get two copies of that element, instead of one copy being in the new list twice." If the elements are references to assets or prefabs I am assuming that the asset or prefab is not duplicated. I would seriously hope not at least. From my experimentation that seems to be how it works. If the data type itself is a prefab GameObject reference for example it does not save a copy of the GameObject only a reference to it.
Sure, of course ;) All links to "real" serialized objects do work as expected. Links to SerializedObjects also work well, but you have to save them "manually" which is often too complicated. That's why a lot people just use MonoBehaviour scripts in such a case. MonoBehaviours support inheritance and can be referenced from multiple other objects without any problem and they are automatically serialized with the GameObject they are attached to.
Hello, I had the same problem with a list of Monobehivour classes that was filled in edit mode.
There was no problem with it until I prefabbed the object that the script was on.
After I prefabbed it when I was going to play mode the data in the list was completely lost. And it fixed when unpacked the prefab. So maybe it’s not only for scriptable objects or play mode. Hope this helps.
This is simple as if you would follow basics of Unity you would know that anything changed during actual Play Scene is not saved. It is allowed to change just for test purposes but after you stop game execution all data will be reseted to its initial values.
if you want the values to be remembered you have to assign them in the script or make some kind of another script to assign them dynamically.
No that is not what my question describes though I may have worded it confusingly. I understand that the instances that exist while playing are separate from those that exist while editing. What I am referring to is an actual PREFAB that is part of my assets. The prefab itself loses its values. Not the instances that exist within the edited scene or runtime scene. The prefab class C instances are losing their data. All their data not just the ScriptableObject data.
Yeah actually I originally wrote it that way and when I started experiencing this problem I tried re-writing it as a ScriptableObject thinking that the serialization would be handled. Sounds like something else is still afoot here yet undetermined. I will revert back to what I had but that doesn't help either.
– Alturis2The cross referencing here may be my issue but I would not expect it to lose everything but rather only that assignment. I will try it without that too and see if that makes a difference. If I were to make such a connection where the link from A to C was private or protected that should resolve as well I would think? Can you explain what you mean by "User Prefab" vs "Model Prefab" The prefabs I have been working with are always just an empty game object where I add script components or child GameObjects within it. Specifically what is your distinction between "User" and "Model"?
– Alturis2Ok as an update I tried removing my custom editor class and letting the default editing widgets do their thing and now it does save the data and restore the data correctly. So something may be wrong with the way I setup my custom editor but it is the same as I have done for other classes that do work.
– Alturis2Thanks for your tips Bunny83. Just to clarify though: "Headsup note: if you put one element in a list (or array) twice, when the list gets serialized, you'll get two copies of that element, instead of one copy being in the new list twice." If the elements are references to assets or prefabs I am assuming that the asset or prefab is not duplicated. I would seriously hope not at least. From my experimentation that seems to be how it works. If the data type itself is a prefab GameObject reference for example it does not save a copy of the GameObject only a reference to it.
– Alturis2Sure, of course ;) All links to "real" serialized objects do work as expected. Links to SerializedObjects also work well, but you have to save them "manually" which is often too complicated. That's why a lot people just use MonoBehaviour scripts in such a case. MonoBehaviours support inheritance and can be referenced from multiple other objects without any problem and they are automatically serialized with the GameObject they are attached to.
– Bunny83