Bunch of useful tools for runtime entities autoring directly from MonoBehaviours.
Handles entity lifecycle, data authoring (including managed components), and UnityEngine.Transform synchronization;
Includes:
EntityBehaviour - Handles Entity creation and lifecycle that is connected to the MonoBehaviour;
IEntitySupplier / IEntityManagedSupplier - Contracts which ensure generic workflow when authoring entities from MonoBehaviours;
SerializedArchetype - Stores EntityArchetype in uint[ ] format to be able to serialize / deserialize it as part of MonoBehaviour, ScriptableObject, or any other Serializable;
ArchetypeLookup - Allows caching deserialized SerializedArchetypes in runtime;
EntityReference / ReferencingExt - Allows accessing “main” Entity if there’s a need to reference other entity;
EntitiesBridge / SystemExt - Contains useful extension methods for MonoBehaviour ↔ Entities communication & system utilities;
Extra buffers system - Allow to insert MonoBehaviour "Update"s into Entities loop without stalling jobs;
EntityTransform - Inserts specified Transform (UnityEngine.Transform) into TransformAccessArray for sync jobs to process;
Thanks for sharing! I think it is a great solution for people that want to use Entities in a mostly GameObject-based project. I do suggest you add a disclaimer somewhere that Entities.Graphics and Unity.Physics are not supported out-of-the-box.
Added an ability to select World where to Entity should be inserted.
And a small UI improvement to allow world name caching.
This should allow multiworld setup. Although, worth mentioning, that MonoBehaviours do not have that support. (GameObjects all exist in single world)
So if identical Entities are required in multiple worlds - multiple instances of MonoBehaviours (prefabs) should be used / instantiated. This will ensure their uniqueness.
Also, World class should have a better way of declaring existing worlds, so that their names can be obtained in editor. Otherwise you’d have to write hacks to store their names from playmode etc.
DOTS Hierarchy window has the same issue, and just displays No World in editor. This is @UT.
Also, need to figure out how to preserve MonoBehaviours / prefabs as is in subscenes (in Entities 1.0).
So that they won’t get stripped (in a generic way without writing more than one Baker).
If anyone knows, please let me know.
Currently Entity is not created, if behaviour is on a gameObject in a subscene.
This behaviour is identical to ConvertToEntity.
Hi, (this is identical to github’s answer, posting here in case if anyone else might need it):
If you’re using system to alter state, simplest solution would be to add actual MonoBehaviour to the entity.
And then use system to notify the behaviour. Also, make sure to put managed system into AfterSimulationGroup to avoid job stalls.
Depending on whether its IEntityManagedSupplier or IEntitySupplier, you can do add it in SetupEntity: entityManager.Add(entity, this) [equivalent to EntityManager.AddComponentObject(entity, UnityEngine.Object)]
or via _entityBehaviour.Add(this)
Add tag component to the entity by any means;
Then via managed [SystemBase] system you can query that component directly and do whatever needed.
E.g. via EFE:
Entities.ForEach((in SomeBehaviour behaviour) => behaviour.DoSomething()
.WithAll<HitComponent>()
.WithStructuralChanges() // Probably will be required if you're altering Entity state via DoSomething
.WithoutBurst()
.Run();
Also, I’ve kinda forgot to update this thread for a while.
Latest version is 1.0.5, mostly API consistency changes & minor bugfixes to the editor.
Hi @VergilUa , thanks a ton for sharing this! You’ve just saved me probably the worst two+ weeks of trying to port my Netcode for Gameobjects based project to ECS!
Here’s the TLDR version:
How would you suggest generating entity archetypes based on collections of ScriptableObject scripts that define all of the traits and behaviors of an object as a list of ScriptableObject behaviors?
My setup is a bit atypical, and after digging into this for a bit I’m still scratching my head, so I thought I’d ask for your input. Here’s my situation:
All objects in my game are defined by a ScriptableObject based “dictionary” (word dictionary, not CS dictionary)
All “object definitions” in the dictionary are simply a collection of ScriptableObject based “concepts” that define the object’s behavior, health, move speed, the GO prefab to spawn into the world, etc.
Several “object definitions” share a common GO prefab, but have very different behavior.
For example, “pyromaniac” is the same GO prefab as “pirate”, but the definition of the character’s traits, AI behavior, starting gear sets, etc are all based on a list of ScriptableObject “concepts.”
An example “concept” is “walking”, which has several different SO instances defining different behaviors. One for the “human” objects, one for “zombie” with a slower walk speed and different animation, etc.
When an object is spawned at runtime (as all objects are as the world is entirely procedural), the “object definition” is used to instantiate its associated GO prefab and customize it’s size, materials, gear, stats like health, AI controller, etc.
When the “object definition” prefab GO is spawned, I want to instantiate an entity prefab stored in the scriptable object script.
So “pirate” will have a different Archetype than “pyromaniac” or “zombie.”
My issue is that the GO prefabs have NO entity based information associated with them, but the “object definition” scriptable objects DO. Specifically, many of the underlying “concepts” that make up an “object definition” need to add one or more components to the archetype at design time, so when the GO prefab is instantiated at runtime the backing archetype is instantiated as well. The GO is being treated simply as the “presentation layer” of the underlying entity simulation.
Hopefully that makes sense lol.
So the question is, how would you suggest I go about making the ScriptableObject based “concepts” and “object definitions” gather the required Component data, store it in a serialized Archetype, and instantiate that Archetype at runtime with the GO prefab? I want to try to use EntityBehaviour since it looks like it’s the perfect thing for how I handle object pooling.
Any guidance would be appreciated, thanks again for this awesome plugin!
Hi. Archetype serialization is pretty much an extra optimization layer on top of EntityCommandBuffer writing.
Main goal of which is to skip add commands and frequent archetype changes. GatherEntityTypes can be skipped completely at the a minor cost of extra add commands & archetype changes. Its likely to be just fast enough depending on the numbers.
There are a couple of choices:
If your entities are completely procedural and non-defined in editor time - you can write anything really into the ECB and it will spawn as is. Adding component would require an extra add command though.
Access respective Entity and Buffer from the EntityBehaviour. Then call SetupEntity for the desired IEntitySupplier (can be anything, literally) with them as parameters (similar to EntityBehaviour.SetupEntity). SetupEntity would look like as a constructing dynamic entity in runtime [without archetypes]. Pretty much Entities without baking.
If you can gather them from somewhere (non-runtime generated), like a specific SO reference from the MonoBehaviour. Or a set of SOs - implement IEntitySupplier for them. Then call GatherEntityTypes & SetupEntity on sets of SO (or chain them). All types and data would be automatically gathered from SO.
Mixed approach:
Generalize data (e.g., use enums for logic paths instead of separate systems);
Write all possible types to the GatherEntityTypes in MonoBehaviour;
Add a separate MonoBehaviour with IEntitySupplier and a potential set of SO’s;
Call into something like Initialize(PooledList buffer);
Perform manual SetupEntity on each SO in the buffer and write actual data to the ECB.
And for the really unique entities - generalize and write separate data types via separate MonoBehaviours.
As long as presentation prefab can be swapped - there can be any number of unique archetypes.