Hi All,
I have a question about Entity Link. It is a pretty cool feature and I would like to use it, but using it causes the Entities Retained exception to trigger.
I have it set up exactly as in the Match-One demo with Link in AddView and Unlink in RemoveView systems respectively. However, when I change scenes or hit my Retry button which resets the games I get the Entities Retained exception.
I then added a TearDown method to my AddView system making sure to Unlink entities in an effort to solve this:
```C#
public void TearDown() {
GameEntity[] viewElements = viewsGroup.GetEntities();
for (int i = 0; i < viewElements.Length; i++) {
GameEntity entity = viewElements[i];
entity.view.gameObject.Destroy(); // This extension method first calls Unlink and then Destroy
}
}
But the exception still occurs. I then modified the EntityLink mono behaviour to always unlink when it was being destroyed by adding the handler for monobehaviour OnDestroy
```C#
void OnDestroy() {
this.Unlink();
}
But the exception keeps on appearing. If I don't use EntityLink at all I don't get it so it must be a retention error with it. Any help on this topic? :)
Thanks!
Sounds like you're calling context.Reset() or context.DetroyAllEntities(). Is your RemoveViewSystem reactive?
That's an interesting (and probably common) use-case... context.DestroyAllEntities() actually throws when detecting retained entities to warn you the hard way, that you might leak.
Since I guess your RemoveView system is reactive, it didn't unlink yet, so entities are still retained.
Solutions:
e.isDestroyed = true and execute the systems againboth solutions don't really seems to be optimal, so if you have more ideas let me know.
Thanks for the reply @sschmid . Yes I am calling context.Reset() when I get that error, but the AddViewSystem implements ITearDown with the method implementation above, i.e. getting all entities with view and manually unlinking them while calling systems.TearDown() before context.Reset().
This line entity.view.gameObject.Destroy() does both Unlink() and Destroy() in that order.
That's why this issue is very weird for me :D
Oh man, what a silly mistake :) I named my extension method Destroy which does Unlink() and Destroy() but that was actually conflicting with a Unity method and was not reported by my IDE nor Unity itself :D
It wasn't ever called to manually Unlink the Entity Link. I just renamed it to UnlinkAndDestroy() and this works now. Yeah it is not really clean, as I need to have my own TearDown system which handles this but that's fine I think :)
As a suggestion, maybe we can have an EntityLink component and an EntityLink reactive + teardown system in the default Entitas add ons which adds EntityLink to game objects and makes sure to unlink them on TearDown? That would be a cool use case for the new kits system right? @sschmid :D
Totally, perfect fit :) I hope this idea with Kits and Modules will work somehow.
I'm not certain this issue is actually resolved. I think this is an execution order problem.
tl;dr the linked gameobject may be destroyed before you unlink and release. You may still throw exceptions _unless_ you do an unlink check in _every_ monobehavior interested in the EntityLink.
You can create something like EntityLinkTeardownSystem that calls Unlink() on any View during TearDown(), but you will still _sometimes_ hit the retention exception because during Destroy() the GameObject with the entity link may be destroyed before your teardown system is called. You'll end up with entities retained by instances of an entity link that you can't unlink and release anymore.
Q: Why don't you just make sure the Entity Link ensures it releases its entity, then?
// In EntityLink.cs
private void OnDestroy()
{
if (_entity != null) Unlink();
}
So, that does work and you _still_ get the retention exception, only the retained entity is destroyed as expected.
The only method I've found that avoids all exceptions is doing both the teardown system and also unlinking in the EntityLink.
*edit for clarity
Yeah I since started getting retention exceptions but they were not constant, I couldn't pinpoint what game states triggered them. I'll investigate further these days.
I believe I am getting this same error. I'd love to track it down but I'm finding it hard to even know which entity is being retained.
This is how systems are being taken down.
private void OnDestroy()
{
// This event notifies Views to unlink
if (EcsDestroyedEvent != null) EcsDestroyedEvent();
_updateSystems.TearDown();
_fixedUpdateSystems.TearDown();
_updateSystems.DeactivateReactiveSystems();
_fixedUpdateSystems.DeactivateReactiveSystems();
_updateSystems.ClearReactiveSystems();
_fixedUpdateSystems.ClearReactiveSystems();
_contexts.Reset();
}
And this is the error that appears on scene change.

Does anyone have a suggestion on tracking down which Entity isn't clearing? I can get rid of this error message if I never even link Views to entities, but it's a great debugging tool so I'd love to use it! Thanks!
There does seem to be a race condition. This error does not always occur. Which means these are terrible reproduction steps I know. 馃槗
Hey @GarthSmith did you resolve your problem? I think i might have the same one. :/
Did this ever get solved? It seems like it's a fundamental requirement of any Unity Entitas game so we need a deterministic, solid solution. I've hit the same issue and am not sure how to resolve it
I've got the same error and my problem is that I don't Unlink all entities before change scene. As I know when we change the scene, all entities have been destroyed. Thus, I get Group for all entities with View component and Unlink it. After that, I change the scene and it works well