Hi, I'm trying to render my first pure ECS entity. I found in a lot of posts that RenderMesh and LocalToWorld are the components needed to see the entity rendered. But with the following code, nothing renders. Code (CSharp): public class BoardGenerator : MonoBehaviour { public List<int2> TileCoordinates; public Mesh Mesh; public Material Material; public float Padding; private EntityManager _entityManager; private EntityArchetype _tileArchetype; private List<TileComponent> _tiles; private float _meshWidth; private float _meshHeight; private RenderMesh _renderMesh; void Start() { _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; _tileArchetype = _entityManager.CreateArchetype( ComponentType.ReadWrite<TileComponent>(), ComponentType.ReadWrite<RenderMesh>(), ComponentType.ReadWrite<LocalToWorld>(), ComponentType.ReadWrite<Translation>(), ComponentType.ReadWrite<RenderBounds>()); var meshCenter = Mesh.bounds.center; _tiles = new List<TileComponent>(); _meshWidth = Math.Abs(Mesh.bounds.max.x) - Math.Abs(meshCenter.x) + Padding; _meshHeight = Math.Abs(Mesh.bounds.max.y) - Math.Abs(meshCenter.y) + Padding; _renderMesh = new RenderMesh { material = Material, mesh = Mesh, subMesh = 0, castShadows = ShadowCastingMode.On, receiveShadows = true }; InitializeBoard(); } private void InitializeBoard() { foreach (var tileCoordinate in TileCoordinates) { CreateTile(tileCoordinate.x, tileCoordinate.y); } } private void CreateTile(int tileCoordinateX, int tileCoordinateY) { var tile = _entityManager.CreateEntity(_tileArchetype); _entityManager.SetSharedComponentData(tile, _renderMesh); _entityManager.SetComponentData(tile, new RenderBounds { Value = new AABB { Center = Mesh.bounds.center, Extents = Mesh.bounds.extents } }); _entityManager.SetComponentData(tile, new Translation { Value = new float3( tileCoordinateY * 0.5f * _meshWidth + tileCoordinateX * _meshWidth, 0, tileCoordinateY * 0.75f * _meshHeight) }); _entityManager.SetComponentData(tile, new LocalToWorld { Value = new float4x4( quaternion.identity, new float3( tileCoordinateY * 0.5f * _meshWidth + tileCoordinateX * _meshWidth, 0, tileCoordinateY * 0.75f * _meshHeight)) }); var tileComponent = new TileComponent { XCoordinate = tileCoordinateX, YCoodrinate = tileCoordinateY }; _entityManager.SetComponentData(tile, tileComponent); _tiles.Add(tileComponent); } } What did I missunderstood ?
The "intended" way to create entities now is to use the conversion workflow. Any time you see some tutorial or youtube video talk about "Pure ECS" - including that one - they're probably working off outdated information or they just haven't read up on how the conversion system works. Anyways, you should clone the github samples and try to learn from those (the readmes are detailed and up to date) and the manual. Most other info you find out there is probably out of date.
@Sarkahn From my (very limited) understanding, the conversion workflow is basically "use the editor to create GameObjects and then magically convert to DOTS". I don't want to do that. I want to create entities from code. I was able to do the above video in Unity 2020.2 and everything worked. If there is a better way of doing so via DOTS, please let me know. I'm new to Unity and DOTS and generally would like to do things in code not via the editor. (I'm interested in procedurally generated/authored content)
I hear you - literally everything I've done in dots has been procedurally generated! But there's really nothing "magic" about conversion - it's complicated for sure but the documentation is getting better. And even for procedural generation I use the authoring workflow to set up prefabs and editor tools, it's actually very useful. As an example - I have a couple of different "monsters" I spawn in my map - a goblin and an orc. Because it's ECS there's obviously no "Goblin" or "Orc" class, they're just entities comprised of components, but I can still set them up entirely in a prefab: So I have a nice list of easily tweakable components for my prefabs. Then in my map authoring script I just reference the prefab: Then when the map is converting it can convert the prefabs to their entity representations via the IDeclareReferencedPrefabs interface. And I can spawn my monsters procedurally in the code. And just to be clear - at runtime I am spawning the entity representation of my prefabs, there are no gameobjects at runtime. By using the conversion workflow you can make it really easy to set up and tweak the elements of your procedural generation completely through the editor which is incredibly useful for fast development and experimentation. Hopefully that all makes sense!
Thanks Sarkahn, I definitely can believe that using the conversion workflow is the best way to prototype / iterate. I will give it a try.
Myself I generate most stuff procedurally. However, I use GO conversion work flow, to get besics meshes into entity format as prefabs. This is so, it is easier to manipulate and test materials and shader on GO via inspector, between runtimes. Then I create more complex DOTS entities prefabs if needed, by adding required components via code. So for example, I can convert base cube into entity prefab. Then have derived multiple prefabs from that, sharing same mesh, but having different functionality, defined by corresponding entity components.
Sorry. This is an great series with 9 videos. 1) Unity Dots: Creating an Enity, where he explains base principles and refers at the beginning to the next video.... 2) Unity Dots: Conversion Workflow ... Judging a video without having seen it and claiming probabiltys "they're probably working off outdated information" helps noone. Just saying.
I did skim the video, and saw that in it he's calling into the DefaultGameObjectInjectionWorld from a Monobehaviour to manually create entities in code. That's how I reached the conclusion that it was not a great intro to entities, a conclusion I stand by. Anyways, this is a screenshot from the end of that "Conversion Workflow" video: This will technically work (for now) but manually calling into conversion at runtime is going to be deprecated so in my opinion it has no place in a tutorial. The intended way to do what he's doing above would be to write an IConvertGameObjectToEntityScript with IDeclareReferencedPrefabs. That defines the conversion in a way that's future proof and can be used with subscenes or with the ConvertToEntity script. And for the record saying someone is working from outdated information isn't a criticism on them - if anything it's Unity's fault for giving us almost no documentation on conversion until very recently.
Just found the series very helpful. Subscens and further method follow in video 3 and 4. It s a little hard to get because videos don t have numbers. But in the right order there is a pretty good cover.... Unity DOTS: Creating an Entity https://youtu.be/H-goqMxN0Bc Unity DOTS: Conversion Workflow https://youtu.be/wsohegMV6fk Unity DOTS: Components and Systems https://youtu.be/HdJHk0moJ7c Unity DOTS: C# Job System https://youtu.be/E8VNVTsRE4I Unity DOTS: System Base " DOTS Gameplay: Basic Player Input and Movement: https://youtu.be/lFl2SMfhvoA DOTS Gameplay: Tags: https://youtu.be/6iNXkR3ukD0 DOTS Gameplay: ComponentDataFromEntity: https://youtu.be/UUCv2nDAKg4 DOTS Gameplay: EntityQuery https://youtu.be/IuoKWupJ6zo DOTS Gameplay: Trigger Events https://youtu.be/jga3nj_Ott4 DOTS Gameplay: Collision Events
Those later videos definitely look much better in terms of what I'd expect "normal" ECS code to look like IE: Not awkwardly calling into DefaultGameObjectInjectionWorld from inside a monobehaviour to try and do everything. Again I only skimmed them but from from the SystemBase video on it seems like it would be a fantastic intro to ECS!