Problem in RenderMesh sortings

I am writing a convertor to covert SpriteRenderer gameobjects to entity with RenderMesh component.

using Unity.Entities;
using Unity.Rendering;
using Unity.Transforms;
using UnityEngine;

namespace OpenEcsTools
{
    [DisallowMultipleComponent]
    public class ConvertSpriteToEntity : MonoBehaviour
    {
        private EntityManager entityManager;
        private void Awake()
        {
            // access the active entity manager
            entityManager = World.Active.EntityManager;
            // search through all childs of this object
            foreach (Transform child in transform)
            {
                int childComponentCount = child.GetComponents<Component>().Length;
                // if we are checking the current object and it only
                // has a transform and this component, ignore making an entity
                if (child == this && childComponentCount == 2) continue;

                // if the child only has a transform component, dont convert it to entity
                if (childComponentCount == 1)
                {
                    Debug.Log(string.Format("Ignore onverting {0}, it is an empty game object", child.name));
                }
                else
                {

                    // create a new entity for each child
                    var entity = entityManager.CreateEntity();

                    // set entity name to its game object name
                    entityManager.SetName(entity, gameObject.name + "/" + child.gameObject.name);

                    SpriteRenderer spriteRenderer = child.GetComponent<SpriteRenderer>();
                    if (spriteRenderer != null)
                    {
                        Sprite sprite = spriteRenderer.sprite;

                        // create a new mesh for each sprite renderer
                        var newMesh = new Mesh();

                        // create vector3 array for all vertices and copy from sprite renderers sprite vertices
                        Vector3[] vertices = new Vector3[sprite.vertices.Length];
                        for (int i = 0; i < sprite.vertices.Length; i++)
                            vertices[i] = sprite.vertices[i];

                        // assign vertices to the new mesh
                        newMesh.vertices = vertices;

                        // create a new int[] for all triangles same as what we did for vertices
                        int[] triangles = new int[sprite.triangles.Length];
                        for (int i = 0; i < sprite.triangles.Length; i++)
                            triangles[i] = sprite.triangles[i];

                        // assign tirangles to mesh
                        newMesh.triangles = triangles;

                        // assign sprite uv to mesh uv
                        newMesh.uv = sprite.uv;

                        // Add local to world component, RenderMesh component needs this to show its mesh
                        entityManager.AddComponentData<LocalToWorld>(entity, new LocalToWorld());

                        // assign a material
                        Material newMaterial = new Material(spriteRenderer.sharedMaterial);
                        newMaterial.mainTexture = sprite.texture;
                        newMaterial.color = spriteRenderer.color;

                        // Add render mesh component to new entity
                        entityManager.AddSharedComponentData<RenderMesh>(entity, new RenderMesh()
                        {
                            material = newMaterial,
                            mesh = newMesh,
                            castShadows = UnityEngine.Rendering.ShadowCastingMode.Off,
                            receiveShadows = false,
                            layer = spriteRenderer.sortingOrder
                        });

                        // add translation component to new entity
                        entityManager.AddComponentData<Translation>(entity, new Translation()
                        {
                            Value = new Unity.Mathematics.float3(
                                child.position.x,
                                child.position.y,
                                -spriteRenderer.sortingOrder)
                        });

                        // if sprite is rotated, add rotation component too
                        if (child.rotation != Quaternion.identity)
                            entityManager.AddComponentData<Rotation>(entity, new Rotation() { Value = child.rotation });
                    }
                }
            }
            Destroy(gameObject);
        }
    }
}

I have used spriteRenderer.sortingOrder value for RenderMesh.layer.
The problem is that object render sorting will not care about this parameter and each gameObject has higher position in hierarchy will be render over others.
I also tried to bring front entities near the camera in Z axis but they will render under the background.

Editor:

PlayMode:
5027510--492683--upload_2019-10-3_10-26-22.png

What am I missing here?

Can you offer better ways to convert sprite renedrers to entities?

I have the same issue, please let me know if you have managed to solved it!

The current implementation of RenderMesh isn’t a general purpose rendering system. It lacks many of the features you need in any specific use case, so your only option is to wait till Unity comes out with an update to it or write your own rendering system as most people on this forum have already done.

An example:

The simplest way (not necessary best) is likely to ditch the hybrid tenderer and draw the sprites with drawmeshinstanced indirect.

assuming your sprites all use the same material, you just have to draw the chunks in order of the layer value (since you assign The sorting layer, they are already split in different chunks)

1 Like

thanks a lot for the solutions and answers, trying it now :slight_smile: