Hybrid renderer - cannot render entities

Hi,

for the last few days I’ve been trying to create a small, 2.5D, grid based proc-gen map using DOTS - Entities 0.51 (I have about some experience with GO based Unity workflow, but zero with DOTS). I have an issue with rendering my map tiles, here’s the rendering code:

[UpdateInGroup(typeof(PresentationSystemGroup))]
public partial class MapRendererSystem : SystemBase
{
    public Mesh TileMesh;
    public Material TileMaterial;
    private bool _mapRendered = false;

    protected override void OnUpdate()
    {
        if(_mapRendered)
        {
            return;
        }

        var ecb = new EntityCommandBuffer(Allocator.TempJob);

        var renderMeshDescription = new RenderMeshDescription(
            TileMesh,
            TileMaterial,
            shadowCastingMode: UnityEngine.Rendering.ShadowCastingMode.Off,
            receiveShadows: false);

        var tileQuery = EntityManager.CreateEntityQuery(new EntityQueryDesc
        {
            None = new ComponentType[] { typeof(RenderMesh) }, // just to be safe
            All = new ComponentType[] { ComponentType.ReadOnly<TileComponent>() }
        });

        var tileEntities = tileQuery.ToEntityArray(Allocator.TempJob);

        foreach(var entity in tileEntities)
        {
            RenderMeshUtility.AddComponents(
                entity,
                ecb,
                renderMeshDescription);
            EntityManager.AddComponentData(entity, new LocalToWorld());
        }

        //Dependency.Complete();

        ecb.Playback(EntityManager);
        tileEntities.Dispose();
        tileQuery.Dispose();
        ecb.Dispose();

        //var renderTilesJob = new RenderTilesJob();
        //var renderTilesJobHandle = renderTilesJob.ScheduleParallel();
        //renderTilesJobHandle.Complete();

        _mapRendered = true;
    }

    partial struct RenderTilesJob : IJobEntity
    {
        void Execute(ref LocalToWorld localToWorld, in TileComponent tile)
        {
            localToWorld.Value = ComputeTransform(tile);
        }

        private float4x4 ComputeTransform(TileComponent tile)
        {
            return float4x4.Translate(new float3(tile.Position.y, tile.Position.y, 0));
        }
    }
}

public struct TileComponent : IComponentData
{
    public int2 Position;
    public TileType TileType; // just an enum
}

so I have a few questions:

  1. the above code does generate entities with LocalToWorld, RenderMesh etc. components, however they do not actually appear in the game. If I uncomment the following part:

//var renderTilesJob = new RenderTilesJob();
//var renderTilesJobHandle = renderTilesJob.ScheduleParallel();
//renderTilesJobHandle.Complete();

then no HybridRender components get attached to the entities at all, only TileComponents are attached. What am I doing wrong?

  1. how should I properly load meshes and materials into SystemBase classes? I’m currently using a MonoBehaviour class like so:
public class MapRenderSystemFeeder : MonoBehaviour
{
    public Mesh TileMesh;
    public Material TileMaterial;

    void Start()
    {
        var world = World.DefaultGameObjectInjectionWorld;
        var mapRendererSystem = world.GetExistingSystem<MapRendererSystem>();
        mapRendererSystem.TileMesh = TileMesh;
        mapRendererSystem.TileMaterial = TileMaterial;
    }

}

surely there is a better way? Initially I tried the GO approach, like this: Runtime entity creation | Hybrid Renderer | 0.51.1-preview.21 , however I’m not sure if this is correct for real-world games?

  1. How to make sure a System only does 1 cycle of work? I currently use this:
        if(_mapRendered)
        {
            return;
        }

to make sure the System only works once. But it’s probably wrong?

Hi, You can disable automatic updating on the system base and just call Update() from outside.
Or just use OnCreate(). I would probably, if I where you just go through the ecs examples.
In other case yea thats one way to do it.

Also don’t try to manually create these entites. Especially since you are new. You can use the authoring component to just connect prefab and let the engine do the ecs prefab thing for you.