Currently playing with ECS and got to the point where I want to disable default bootstrap completely and create and configure my world manually. Im trying to keep thisng as simple as possible. Currently I have this
public class Game : MonoBehaviour
{
private World _world;
private InputSystem _input;
/* +3 more systems */
private void Awake()
{
_world = new World(gameObject.name);
_input = _world.GetOrCreateSystem<InputSystem>();
/* +3 more systems */
}
private void Start()
{
/* here I create a test entity with RenderMesh and stuff */
}
private void Update()
{
_world.Update();
}
}
While it was working great with default world and bootstrap, now it is broken.
According to Entity Debugger, default world still exists and populated with my systems.
There are no systems in my custom world, only the enity I created
Nothing gets rendered on the screen.
It looks like I missed something obvious. Maybe there’s some example on how to disable all that magic stuff and create custom world being able to render a mesh in a simple and clean manner?
Finally, I’d like to have two worlds for simulation and game logic splitted to call simulation Update from Fixed update and logic and update from regular update. After that, I’d like to update the UI impleneted in monobehaviours. Is this a correct approach at all?
public interface ICustomBootstrap
{
// Returns the systems which should be handled by the default bootstrap process.
// If null is returned the default world will not be created at all.
// Empty list creates default world and entrypoints
List<Type> Initialize(List<Type> systems);
}
I’ve installed Entities 0.3 preview and what I’ve got is
public bool Initialize(string defaultWorldName)
{
_world = new World(nameof(Game));
_input = _world.GetOrCreateSystem<InputSystem>();
/* more systems here */
_output = _world.GetOrCreateSystem<OutputSystem>();
return _world.IsCreated; // debugger says it's True here
}
And default worlds disappeared, now there’s only one world in entity debugger, but there are no systems shown and no entities at all.
There’s a warning in the console saying
You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
My game manager is set up as MonoBehaviour on active game object in the scene, but that Initialize method is invoked before scene load and Unity creates another instance of my bootstrapper without any game object (this.gameObject == null in debugger). Looks like I starting to undertand how it works, but more changes required to make my code do what I want.
Is there any more docs or examples with actual implementation or only outdated ones?
Also how to reference intial setup? I have some game options saved as scriptable object and my mono behaviour references it from scene. What would be best approach to this problem if I can’t use behaviour for game manager? Im thinking of using addressable currently, but I don’t see convenient way of doing it visually through some default editor workflow. Like a click there, drag that thing into this slot, settings changed, or something like this.
Also I probably need to add transformation and rendering systems manually since I’ve disabled default bootstrap? Maybe any docs for that or I should just look onto default world setup and do it likewise?
The best docs for ICustomBootstrap are actually in the Changelog.
class MyCustomBootStrap : ICustomBootstrap
{
public bool Initialize(string defaultWorldName)
{
Debug.Log("Executing bootstrap");
var world = new World("Custom world");
World.DefaultGameObjectInjectionWorld = world;
var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);
return true;
}
}
Once you have the list of systems, you don’t need to call AddSystemsToRootLevelSystemGroups. You can manually instantiate your systems and groups or insert them into multiple different worlds however you want.
UpdatePlayerLoop just grabs the InitializationSystemGroup, SimulationSystemGroup, and PresentationSystemGroup in the World and injects delegates for them into the player loop.
Thank you very much, this is exactly what I need. As for configuration, I just can catch up the world in mono behaviour and create entities according to config configured in the scene. This splits the initialization into two parts, and this make sense. I can create worlds and populate worlds and it is two different operations, nice