2
\$\begingroup\$

In my game I have a MonoBehaviour WorldView that, when created at editor time, initializes a large dictionary. Later from a Editor WorldViewEditor I call WorldView.SetBlock() that tries to access this dictionary, but finds it empty.

If I understand correctly this is because my editor doesn't access the same WorldView instance, but rather a copy it received through serializing and de-serializing my original instance.
Pushing this dictionary through the serializing process is a performance nightmare and not supported by Unity out of the box.

This dictionary should never be shown in any editor, is private to the instance and initialization will be called every time the scene is loaded.
This sounds like a perfect case for keeping it somewhere outside the serialization process.

I could try to leverage ISerializationCallbackReceiver but this still requires me to pull the entire dictionary through some serialization process.
I'm looking into keeping everything state related in a separate library outside of unity, but this has it own downsides.

Is there a way to put this dictionary in a place where its state is kept?

\$\endgroup\$
2
\$\begingroup\$

The problem with what you're trying to do is that Unity has to recompile your scripts and reload the DLLs every time you make a change, which wipes out all of your non-serialized values, including static fields. Serialization isn't just how they save your scenes and prefabs to disk, it's also how they restore the editor's state every time you compile.

Every time the little wheel in the bottom right hand corner spins, something like this happens:

  1. Serialize every managed object in the Unity editor, including EditorWindows and MonoBehaviours. This is how Unity remembers the position and state of all your windows, GameObjects, etc. It's also how it restores the original game state after you exit play mode even if you didn't hit Save.
  2. Unload all of your script DLLs. At this point your custom types are all gone. Nothing "exists" in managed land at this point because the runtime has no idea about any of your code.
  3. Recompile your scripts and load the DLLs again.
  4. Now that you have your types back, deserialize everything and recreate all your GameObjects, MonoBehaviours, EditorWindows, etc. Since you don't push your dictionary through the serialization pipeline, it's lost at this point and needs to be reloaded.

Basically without serializing it, there's no way to maintain the state. You would have to reload the dictionary every time your scripts compile, not just once at scene load.

It sounds like you're loading that dictionary from a file on disk, or somehow creating the dictionary programmatically every time. How often does this dictionary change? If it doesn't change often, instead of using an intermediate format like XML you could build it directly into a static readonly field so that it automatically builds itself every time scripts reload without having to squeeze through serialization. The only other option is to let the dictionary serialize. You said it's large, and Unity doesn't support Dictionary serialization right out of the box, so you'd like to avoid this route, which I understand. But there's really no way around the fact that the entire state of the managed application gets wiped every time you recompile.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks. I hadn't considered the automatic compile scenario. The automatic rebuilding scenario sounds OK. Can you elaborate on that? The dictionary doesn't change often and I'm computing it based on a external file at scene creation time. \$\endgroup\$ – Boris Callens Mar 15 '15 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.