I can’t seem to find anything about the order of execution when working with Monobehaviours and System at the same time.
I have a Monobehaviour that needs to do some Spherecasts (I’m using the dots physics) at the start of the game.
When I try to do it in the Start function it seems that the entites haven’t been converted yet.
I then tried just waiting for 1s before running the SphereCast function and it worked fine.
Is there a recommended or good way to wait for things like the entities to convert, before running a Monobehaviour function I would normally run through Start?
I also tried calling the function from OnCreate of one my systems, but then Awake hasn’t run yet and the singletons aren’t initialized yet.
Using a coroutine delay works but seems quite hacky.
There isn’t a built-in way to do so, but most robust way I found is to run Update / other callbacks after ECS simulation.
This can be achieved by creating a custom manager which runs via SystemBase system. Order of which is set to be after SimulationGroup.
E.g.
using Unity.Entities;
namespace EntitiesExt.SystemGroups {
/// <summary>
/// Update group that runs in the simulation group, but after all ECS system / jobs ran / scheduled.
/// This is done in PreLateUpdate
/// Use this one for the hybrid / MonoBehaviour bridged systems
/// </summary>
[UpdateInGroup(typeof(SimulationSystemGroup), OrderLast = true)]
[UpdateAfter(typeof(EndSimulationEntityCommandBufferSystem))]
public class AfterSimulationGroup : ComponentSystemGroup { }
}
So in your case it would be best to wait for conversion to complete, then run ECS update, and run MonoBehaviour Update afterwords in AfterSimulationGroup.
TL;DR:
Queue up an entity from MonoBehaviour either via conversion or manually. (Attach your MonoBehaviour script via EntityManager.AddComponentObject(this) or via conversion). Plus add some component tag to filter already initialized entities.
Run an initialization (spherecast) system with logic you need in AfterSimulationGroup with .WithoutBurst().Run();
Remove tag via query or ECB;
This will align execution order without hacks. And if you’d need to run MonoBehaviour logic from ECS side, you can implement any system in AfterSimulationGroup just fine. E.g. query filtered callbacks / notifications, direct update logic etc.
I’ve got entities extension / hybrid utility for this type of cases, and it simplifies usage of both MonoBehaviours and Entities in the same project. Though it doesn’t use conversion, and relies on authoring entities from MonoBehaviours instead. Which is a bit slower, than conversion workflow, but much more user-friendlier to use (relies on generation of archetypes in editor and generating entities from archetypes in runtime). And it already has custom update manager with other utilities. I’ll upload it github at some point if interested.
MonoBehaviours spawned via Update / Coroutines etc would run callbacks before conversion happens, so that is why this is an issue. (And also before ECS physics ran / initialized)