Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Monobehaviour GO/bootstrap and rendering

Discussion in 'Graphics for ECS' started by Aratow, Oct 27, 2019.

  1. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    Hello!
    I've been digging hard into DOTS as of late and there's a few things I might be misunderstanding;

    All the people I've seen an example or use a monobehaviour script to start an ecs project with a gameobject, place the entitymanager there and the rendering too.
    I understand that you can convert a gameobject into an entity and have a mesh/material serialization on it for rendering, but I couldn't find any examples of anyone doing that work without monobehaviour/gameobject or a "bootstrap" script for entitymanager.
    The impression I had was that one could theoretically use pure ecs to create a project but those usages confuse me.

    I've been looking around a lot, but does someone know of an example that use pure ecs with rendering, and entity creation without gameobjects?
     
    Last edited: Oct 27, 2019
  2. Radu392

    Radu392

    Joined:
    Jan 6, 2016
    Posts:
    210
    Code (CSharp):
    1. public class SpawnerSystem : JobComponentSystem
    2. {
    3.  
    4.    EntityManager entityManager;
    5.  
    6.    protected override void OnCreate() {
    7.      
    8.        entityManager = World.EntityManager;
    9.        for (int i = 0; i < 100; ++i) {
    10.              Entity e = entityManager.CreateEntity(typeof(Translation), typeof(LocalToWorld), typeof(RenderMesh)));
    11.              // set the material and mesh into the rendermesh component of your entity now
    12.         }
    13.    }
    14.  
    15.     protected override JobHandle OnUpdate(JobHandle inputDependencies) {
    16.          return inputDependencies;
    17.     }
    18. }
    19.  
    I still recommend you use one monobehavior to set up your entities and later on when you'll be more comfortable with ECS, your systems. Also, if you need more actual examples and actual explanations, I suggest you look up CodeMonkey on youtube. The guy has some extremely nice up to date tutorials on how to get started with ECS
     
    Last edited: Oct 27, 2019
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,223
    There's two ways MonoBehaviours are used in DOTS. The first is using it to manipulate the EntityManager to set everything up exactly as you described. This is used by people who aren't totally comfortable with DOTS and are testing the waters, or by people who are mixing GameObjects and DOTS.

    The other use of MonoBehaviours is the Game Object Conversion workflow. You'll see a MonoBehaviour implement IConvertGameObjectToEntity most of the time when this is in use. This is the intended "pure" approach right now, as Unity has decided to leverage their existing tech for authoring. They tried going pure for authoring with Project Tiny. It wasn't as good as their current approach.

    The Physics samples are a decent example of using Game Object Conversion.
     
    bb8_1, twobob and MNNoxMortem like this.
  4. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I see. And so I've researched, and it looks like IConvertGameObjectToEntity is just to make workflow with the editor possible.

    I suppose my question is this:
    Can you render an entity with just a mesh and material using RenderMesh without Authoring a GameObject?
     
  5. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Yes. Just create entity in code, set RenderMesh with material and mesh, set LocalToWorld matrix directly or use Translation and\or Rotation and\or Scale and it will add additional componens (bounds etc.) and you'll see entity.
    Code (CSharp):
    1. ecb.CreateEntity(SomeArchetype);
    2.         ecb.SetComponent(new Translation {Value = pos});
    3.         ecb.SetComponent(new Rotation {Value = rot});
    4.         ecb.SetComponent(new NonUniformScale {Value    = scale});
    5.  
    6.         ecb.SetSharedComponent(new RenderMesh()
    7.         {
    8.             material       = mat,
    9.             mesh           = mesh,
    10.             castShadows    = ShadowCastingMode.On,
    11.             receiveShadows = true
    12.         });
     
    siggigg likes this.
  6. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49

    Meaning I'd need to get a reference for the mesh and material myself with:

    Code (CSharp):
    1.         dstManager.SetSharedComponentData(playerEntity, new RenderMesh()
    2.         {
    3.             material = Resources.Load<Material>("Assets/Resources/Characters/PlayerMaterial.png"),
    4.             mesh = SomeCreateMeshFunction()
    5.         }) ;
    Something Like that?
    Still trying to make it work..
     
  7. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Yes, form resources (bad practice, only for prototyping), from asset bundles, addressables etc. But why you're don't want to use conversion workflow?
     
  8. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I'd like to control the entire system using the same structure, and make it clean.
     
  9. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Conversion workflow much cleaner than manual entity creation :)
     
    Aratow likes this.
  10. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    It's also the easier way to do it I guess.
    Thanks!
     
  11. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I've seen a lot about the conversion workflow, explicitly turning a gameobject to entity to gain gameobject/monobehaviour advantages, setting a subscene for the conversion and the like.

    That said, would it be the same to just do
    Code (CSharp):
    1.         entityManager = World.Active.EntityManager;
    2.  
    3.         entity = entityManager.CreateEntity(
    4.             typeof(Translation),
    5.             typeof(RenderMesh),
    6.             typeof(LocalToWorld));
    7.  
    8.         var instance = entityManager.Instantiate(entity);
    in monobehaviour that is attached to an object, then disposing of that object?
     
  12. BackgroundMover

    BackgroundMover

    Joined:
    May 9, 2015
    Posts:
    216
    Instead of putting code in a monobehaviour, then destroying the monobehaviour, you could create a ComponentSystem and put the entity creation logic in its overridden OnCreate() method.

    Or use [RuntimeInitializeOnLoadMethod] over a public static void function and let the code run there. I think monobehaviour scene conversion is better, but they're two alternatives.
     
    Aratow likes this.
  13. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I needed to use texture2d's GetPixel() but couldnt get it written in pure ecs so i wondered if it was a good way to go about it?
    I'm sure you can make a methode similar to GetPixel() in pure ecs, but lets say i just wanna use a mono tool here and there
     
  14. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    There was a discussion about it some time ago here on the forum. I personally never had the need to use it and i don't know if it is still a valid option.
     
    Aratow likes this.
  15. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    Damn! Didn't know GetPixel was that expensive.
    Also thanks! I'm looking into that right now.
     
  16. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Better is get raw texture data as native array and manipulate this (in job for example)
    Edit: I looked at link, yep He suggests same :)
     
    Aratow likes this.
  17. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I've been trying to understand more about native arrays but I'm still not sure how to implement it in this situation..
    Here's what I'm working with:

    Code (CSharp):
    1.  public class : MonoBehaviour
    2.  
    3. public Texture2D mapTexture;
    4.  
    5.    void Start()
    6.     {
    7.  
    8.         for (int x = 0; x < mapTexture.width; x++)
    9.         {
    10.             for (int y = 0; y < mapTexture.height; y++)
    11.             {
    12.  
    13.                 Color pixelColor = mapTexture.GetPixel(x, y);
    14.             }
    15.         }
    16.     }
    17.  
    I'm a bit confused on how to get a native array to basically GetPixel() and store it to later use in a job.

    The only other reference I've found was this from a while back
    https://forum.unity.com/threads/texture2d-could-accept-a-setpixels-with-nativearray-color.527878/?gq=nativearray color ecs
    but it got me even more confused...
     
  18. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    https://docs.unity3d.com/ScriptReference/Texture2D.GetRawTextureData.html
     
  19. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    Yes, I've been looking into that aswell.
    I'm still learning, so excuse my ignorance, but does it mean that i can just call
    Code (CSharp):
    1. public NativeArray<Color32> mapcolorArray;
    2. mapcolorArray = mapTexture.GetRawTextureData<Color32>();
    and that would be the native array i would use in jobs?
    The documentation page shows an example of filling the data.
    So does it mean just calling mapTexture.GetRawTextureData<Color32>() automatically fills that array with the data, or would I need to loop over it?

    Edit: Just tested. Looks like it was that simple and indeed, it automatically loops over the texture =/
     
    Last edited: Nov 14, 2019