Hot Reloads & Live Recompilation - antfarmar/Unity-3D-Asteroids GitHub Wiki
Problem:
Hot-Reloading/Live-Compilation is unforgiving.
When debugging and/or editing code while in playmode, if you save the changes and return to the Unity editor, Unity will hot-reload/live-compile the code. This can be a quite handy time-saver during development, so it is definitely worth investigating this process to be sure your code is compatible with it to preserve it. It is quite touchy, though:
The process goes something like this:
- Unity notices that the code has changed and tries to recompile it.
- It first calls
OnDisable
, recompiles, the callsOnEnable
when finished.
- It first calls
- If the recompilation is successful, Unity does the hot-reload which:
- Serializes everything it can.
- Tears down the managed (Mono) runtime.
- Starts a new managed (Mono) runtime with the new code.
- De-serializes everything it can back into the new runtime.
There are many reasons why this might go wrong:
- Anything which can’t be serialized...won’t be. That data will be lost, leading to null-references.
- Static class members aren’t serialized, leading to null-references.
- Name changes to serialized fields won’t make it through to the new runtime either, leading to null-references.
Further Reading:
Solution
OnEnable
/OnDisable
messages.
Use only serializable types & exploit - Use ONLY serializable types!
- It's not that difficult to emulate Dictionaries/Queues with Lists.
- Limit your static types & singletons.
- Data can be saved
OnDisable
, reassignedOnEnable
- If static types/singleton instances are unavoidable:
- They can be reassigned
OnEnable
. - It worked with the
GameManager
public instance (in the hot-reload branch).
- They can be reassigned
- Be cognizant of what you place in
OnDisable
/OnEnable
.- These Event Messages are called on recompilation start/end, respectively.
- Re-assign/initialize static variables here.
- Don't put place code in here that naturally belongs in
Awake
/Start
.- e.g. Once-only initializations & operations
- Add [FormerlySerializedAs("oldFieldName")] to fields before renaming field.
Considerations
It is better to take advantage of things like dictionaries, queues, static classes, object references, etc, rather than the minor advantages that hot-reloading provides (which is probably not sustainable as a project grows anyhow). One should prefer clean, efficient, readable code and architecture over most things that would sacrifice it.