Entitas
Entitas copied to clipboard
New Playmode Options: No Domain Reload vs. Unique Entities & Event Handlers
What is the current best practice to use Entitas Teardown() / Contexts.Reset() / ...
in conjunction with the new playmode options that are in Unity 2020?
The problem is, that unique entities stay alive; as do the handlers for EntityLinks (or specifically, Events that then try to access GameObjects that are Unity null / destroyed)
I have tried to work with Script Execution Order and OnApplicationQuit()
on my main controller, but... UnityView components get destroyed befor and after the context is being reset. So either I get the "detected retained entities" issue, or Unity's "trying to access a destroyed GameObject" error.
What kind of seems to work, but feels very hacky, is resetting the contexts on Start()
:
private void Start()
{
_contexts = Contexts.sharedInstance;
_contexts.Reset();
and catching the edge case where a UnityView
is destroyed:
private void OnDestroy()
{
//UnityEngine.Debug.Log($"Destroying view {gameObject.name}, linked to {LinkedEntity}");
if (LinkedEntity != null)
gameObject.Unlink();
}
... the latter feels like an inappropriate re-inversion of control, and can have unwanted side effects if something that's not the ~~end of the world~~ Application quit kills the gameobject.
To clarify, object destruction order on application termination appears (kind of naturally/obviously) to be largely detached from script execution order, or occurs in several stages! But OnApplicationQuit() is invoked before all of these. You do not get another tick in between, though.
In my project in test's Teardown we do:
- unlink all gameobjects
- deactivate entitas systems
- clear scene (destroy gameobjects, clear DontDestroyOnLoad scene)
- destroy all entities
- reset entitas contexts
- activate contexts indices
Here is my solution :
Add below method to https://github.com/sschmid/Entitas-CSharp/blob/master/Addons/Entitas.CodeGeneration.Plugins/Entitas.CodeGeneration.Plugins/Context/CodeGenerators/ContextsGenerator.cs
public static Contexts CreateNewInstance()
{
_sharedInstance = new Contexts();
return _sharedInstance ;
}
Recompile Entitas.CodeGeneration.Plugins
Then call this method before any entitas's call.