Search Unity

Trying to use ECS for the rendering process for my existing project

Discussion in 'Graphics for ECS' started by loliconest, Apr 2, 2019.

  1. loliconest

    loliconest

    Joined:
    Sep 21, 2015
    Posts:
    31
    Hello everyone!

    I'm very new to ECS, after watched a few official and non-official tutorials, I decide to try out ECS on one of the project I'm working on.

    The project has a very large and un-optimized scene with tens of thousands of meshes, and I want to change all of the MeshRenderer component on the scene objects to use the MeshInstanceRendererComponent (assume this is the correct way to make the renderer into entity).

    I just tried to do this on one GameObject by removing its Mesh and MeshRenderer component and replace them with the MeshInstanceRendererComponent, and put in the correct mesh and material. However when I run the play mode, I don't see the object being rendered.

    I think I probably missed some critical steps to make this work, but I can't figure out right now, if someone has tried and succeeded to only update the rendering process to use the ECS (meaning everything else are still MonoBehaviour), please give me some help!

    Many thanks!

    -----------------------------------------------------------------Edit:

    I think I start to figure out how to make it to work. Just replacing existing component with MeshInstanceRendererComponent is not enough, I have to have an EntityManager that instantiating the entities at runtime (at least to my understanding).

    I followed these two tutorials:



    But I don't want to instantiate MeshInstanceRenderer entities from a preset, I want to "turn" all my existing scene object into entities at runtime. So what I ended up doing is creating a "meshRenderer" EntityArchetype, then use that as a "preset" to populate the initial MeshInstanceRenderer entity list, then copy the mesh value and material value from my scene objects to the instantiated entities one by one.

    Here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Collections;
    6. using Unity.Rendering;
    7. using Unity.Transforms;
    8.  
    9. public class SceneEntityManager : MonoBehaviour
    10. {
    11.     public EntityManager entityManager;
    12.  
    13.     // Use this for initialization
    14.     void Start()
    15.     {
    16.         entityManager = World.Active.GetOrCreateManager<EntityManager>();
    17.         AddMeshes();
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.  
    24.     }
    25.  
    26.     public void AddMeshes()
    27.     {
    28.         // Create new mesh entity archetype
    29.         EntityArchetype meshRendererArchetype = entityManager.CreateArchetype(
    30.             typeof(Position),
    31.             typeof(Rotation)
    32.             );
    33.         Entity sampleMeshRendererEntity = entityManager.CreateEntity(meshRendererArchetype);
    34.  
    35.         // Get all scene objects with MeshInstanceRendererComponent
    36.         MeshInstanceRendererComponent[] meshInstances = FindObjectsOfType<MeshInstanceRendererComponent>();
    37.  
    38.         // Create new mesh entities
    39.         NativeArray<Entity> meshEntities = new NativeArray<Entity>(meshInstances.Length, Allocator.Temp);
    40.         entityManager.Instantiate(sampleMeshRendererEntity, meshEntities);
    41.  
    42.         for (int i = 0; i < meshInstances.Length; i++)
    43.         {
    44.             entityManager.SetComponentData(
    45.                 meshEntities[i], new Position { Value = meshInstances[i].transform.position });
    46.             entityManager.SetComponentData(
    47.                 meshEntities[i], new Rotation { Value = meshInstances[i].transform.rotation });
    48.             entityManager.AddSharedComponentData<MeshInstanceRenderer>(
    49.                 meshEntities[i], meshInstances[i].Value);
    50.         }
    51.  
    52.     }
    53. }
    -----------------------------------------------------------------Edit 2:

    So I soon realized that my current method only work with GameObjects with only one Material attached to its MeshRenderer, because in a MeshInstanceRendererComponent, I can only put in one Material, instead of multiple materials like a classic MeshRenderer component.

    Does anyone know how to put more than one material in a MeshInstanceRendererComponent?
     
    Last edited: Apr 3, 2019
  2. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    186
  3. loliconest

    loliconest

    Joined:
    Sep 21, 2015
    Posts:
    31