Edit-and-Continue Scripting - Destroys Current State.

I like the semi-Edit-and-Continue feature of Unity because it allows me to insert Debug.Log() dynamically to try and find/fix bugs, and allows me to maintain the current application state where it is. BUT, the achilles heel of this whole thing is that each time I make any small edit to any script -- it invalidates all DLL's (scripting assembly plus other DLL's that I'm using that run on Mono). Therefore, I lose nearly ALL dynamic state.

I have found that the ONLY thing that is "Saved/Restored" are Script Public Fields... which is a good starting point. So I can place some dynamic Fields here, and am then able to restore some of my dynamic state.

But I also have some dynamic state that is stored into an ArrayList of Key/Value types. I have experimented with the concept of saving the entire ArrayList into a Public String Field, on a global component - and this "sorta works". The problem is that when Script Editing occurs -- it happens without warning, so I don't have a good event handler to make the serialization into String occur JIT. I don't want to be doing this every frame, or with every change... that is too wasteful. I'd like to do it JIT.

Is there a global event I can register for that occurs BEFORE the scripts are invalidated and "stored"?? If so, then I can register for this event, and serialize my ArrayList to a public STring Field, that will then be Saved/Restored. On the other side of things, I already have the "OnEnable()" event that gets called, wherein, I can restore saved state from String back to the ArrayList.

This whole thing is a bit kludgy. I'd prefer to NOT be using this kludge, but if there is no other good alternative, then I must use it, else we can't enjoy the benefits of Edit-and-Continue.

In short, my questions are: 1. Is there an event that triggers when a Script is Edited (i.e. invalidated?), that I can register for, that occurs BEFORE Script/Component Fields are saved???

OR, even better...

  1. Is there a better way for me to Save/Restore Dynamic State of my Scripts during Script Editing run-time, for object types that are not predefined by Unity? (e.g. if you can help me get it working for ArrayList, then I'm confident I can make it work for most other types).

NOTE: I also tried making my type ISerializable, hoping that Unity might call this -- but no luck! It only seems to save/restore Public fields.

There is no event. Unity will serialize all your script components, reload the new assemblies, and recreate your script components from the serialized verions. This serialization does not happen with .NET's serialization functionality, but with an internal Unity one. The serialization system used can do the following:

  • CAN serialize public nonstatic fields (of serializable types)
  • CAN serialize nonpublic nonstatic fields marked with the [SerializeField] attribute.
  • CANNOT serialize static fields.
  • CANNOT serialize properties.

Your field will only serialize if it is of a type that Unity can serialize:

Serializable types are:

  • int
  • float
  • string
  • array of a serializable type
  • List of a serializable type (new in Unity2.6)
  • GameObject
  • Components
  • Texture2D
  • AnimationClip
  • All other unity things like that
  • Your custom classes, when you mark them with [Serializable]. (this is a bit of an oversight on our end, as [Serializable] is actually a .net attribute).

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.

Trick: we don't serialize Dictionary, however you could store a List<> for keys and a List<> for values, and sew them up in a non serialized dictionary on Awake(). This doesn't solve the problem of when you want to modify the dictionary and have it "saved" back, but it is a handy trick in a lot of other cases.

For UnityScript users: Fields in c# is a script variable in UnityScript, and [SerializeField] becomes @SerializeField. [Serializable] on a class becomes @script Serializable in a UnityScript

What if I wanted to serialize an “UnityAction” in a scriptable object?