Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Promises

Discussion in 'Project Tiny' started by sniffle63, Jun 20, 2019.

  1. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    363
    Is there any chance of us getting something equivalent to doing this in the C# implementation?


    Code (CSharp):
    1.  
    2.                SceneService.LoadSceneAsync(snakeTailToSpawn).then((SceneReference scene) =>
    3.                 {
    4.                    
    5.                    
    6.                 });
    7.  
     
  2. Dunk86

    Dunk86

    Joined:
    May 10, 2015
    Posts:
    53
    Though promises would be useful for lots of things, honestly the fact that we're trying to use scenes as prefabs is why this is a problem. A standard blocking prefab instantiation is what we need (and is probably on the roadmap). For now, I've done new object instantiation manually as so:
    Code (CSharp):
    1.  
    2. for (int i = 0; i < enemiesToSpawn.Length; i++)
    3. {
    4.     EnemySpawn spawn = enemiesToSpawn[i];
    5.     Entity newEntity = EntityManager.CreateEntity(typeof(Parent), typeof(Sprite2DRenderer), typeof(Translation), typeof(Rotation), typeof(NonUniformScale),
    6.         typeof(LayerSorting));
    7.  
    8.     Translation translation = EntityManager.GetComponentData<Translation>(newEntity);
    9.     translation.Value = spawn.m_position;
    10.     EntityManager.SetComponentData(newEntity, translation);
    11.  
    12.     Sprite2DRenderer renderer = EntityManager.GetComponentData<Sprite2DRenderer>(newEntity);
    13.     renderer.sprite = spawn.m_shipConfig.Sprite;
    14.     renderer.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
    15.     EntityManager.SetComponentData(newEntity, renderer);
    16.  
    17.     NonUniformScale scale = EntityManager.GetComponentData<NonUniformScale>(newEntity);
    18.     scale.Value = spawn.m_shipConfig.Size;
    19.     EntityManager.SetComponentData(newEntity, scale);
    20.  
    21.     EntityManager.AddComponentData(newEntity, new ShipComponent(spawn.m_destination, spawn.m_shipConfig.Speed));
    22.     EntityManager.AddComponentData(newEntity, new HealthComponent(spawn.m_shipConfig.Health, spawn.m_shipConfig.CollisionGroup));
    23.     EntityManager.AddComponentData(newEntity, new ResourceRewardComponent(spawn.m_shipConfig.RewardType, spawn.m_shipConfig.RewardAmount));
    24.     if (spawn.m_shipConfig.ShootingComponent.BulletSprite != Entity.Null)
    25.     {
    26.         EntityManager.AddComponentData(newEntity, new ShootingComponent(spawn.m_shipConfig.ShootingComponent));
    27.     }
    28. }
    29.  
     
  3. Frickinlaser

    Frickinlaser

    Joined:
    Jan 19, 2014
    Posts:
    22
    What's the reasoning behind initializing some components in CreateEntity, getting them and updating, and some components directly in AddComponentData?

    Code (CSharp):
    1.  
    2.     Entity newEntity = EntityManager.CreateEntity(typeof(Parent), typeof(Sprite2DRenderer), typeof(Translation), typeof(Rotation), typeof(NonUniformScale), typeof(LayerSorting));
    3.  
    4.     Translation translation = EntityManager.GetComponentData<Translation>(newEntity);
    5.     translation.Value = spawn.m_position
    6.     EntityManager.SetComponentData(newEntity, translation);
    7.  
    8.     ...
    9.  
    10.     EntityManager.AddComponentData(newEntity, new ShipComponent(spawn.m_destination, spawn.m_shipConfig.Speed));
    11.  
    [/QUOTE]
     
  4. Dunk86

    Dunk86

    Joined:
    May 10, 2015
    Posts:
    53
    [/QUOTE]
    No reason.
    I assumed that you can't create an entity without at least the basic elements (Translation, Rotation), and I also wanted some components added with default values only. Honestly, this is just my code from messing around, but you can take it as an example that highlights the alternate ways to do it if you like :)
     
  5. Frickinlaser

    Frickinlaser

    Joined:
    Jan 19, 2014
    Posts:
    22
    No reason.
    I assumed that you can't create an entity without at least the basic elements (Translation, Rotation), and I also wanted some components added with default values only. Honestly, this is just my code from messing around, but you can take it as an example that highlights the alternate ways to do it if you like :)[/QUOTE]

    I see :). I'm in the same boat trying different things. But yes, it seams like you can just create an entity without anything else. I'm curious though about if it matters somehow to think about the archetype. Like if there's some performance boost to try to set it up with those components that doesn't change during the game. But I'm deep in the weeds now talking about stuff I know little about :)
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,652
    It's performance reason. If you create entity from CT array or from archetype it creates chunk and SetComponentData only changes values inside chunk. But if you just create entity and sequentally adds components it's changes archetype every time and moves entity to defferent chunks.
     
    sniffle63 likes this.
  7. Frickinlaser

    Frickinlaser

    Joined:
    Jan 19, 2014
    Posts:
    22
    Right, I see. But if you create it and add components in the same tick, does the archetype change at all, or is it set after OnUpdate anyway?
     
  8. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    363
    What are you using for the Sprite2DRenderer sprite? My entity isnt showing up, but my system running on it says it exist, so im assuming its my sprite not showing up on the 2dRenderer. I was using a Sprite2D and accessing the image (Sprite2D.image) of it to set to the Sprite2DRenderer's sprite
    rider64_2019-06-20_19-14-20.png
    rider64_2019-06-20_19-14-37.png

    I changed the color to black and got rid of the image, and it works for my use case. But if you can get back to me on how your assigning the sprite, would be great :D
     
    Last edited: Jun 21, 2019
  9. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,652
    It’s doing memcopy immediately, cos by EntityManager you’re doing structural changes, and it invalidates chunks immediately. This is why batched overloads, creating from archetypes etc. is better for performance.
     
  10. Dunk86

    Dunk86

    Joined:
    May 10, 2015
    Posts:
    53
    The sprite is assigned from a field on the spawner component called:
    [EntityWithComponents(typeof(Sprite2D))]
    public Entity Sprite;

    Then you can do renderer.sprite = spawnerComponent.Sprite;
    for example.
    My actual code is a little more complicated because I use an intermediate step to store a list of ships to spawn, then iterate through that list to do the actual spawning (since you can't add entities from within a ForEach)
     
    Last edited: Jun 23, 2019
  11. Frickinlaser

    Frickinlaser

    Joined:
    Jan 19, 2014
    Posts:
    22
    Alright, so when you know what components will be added when you create the entity, it's best to add them by archetype or list of component types directly and then fetching them and setting them. Thanks for the insight!
     
  12. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    363
    So you have your sprite drag and dropped on an entity field?
    Or you have an entity with a sprite2DRenderer, and your just accessing the sprite of the sprite2DRenderer.

    I dont really get what your saying, sorry(probably because iv already tried dragging my graphic into an Entity field).

    But i already assumed thats what you were doing with the EnemySpawn, i just wasnt sure what you were storing EnemySpawn as.

    I assumed it was an IComponentData with fields set up on it. I got mine to work by storing a Sprite2DRenderer on another entity's custom component, but i wasnt able to access the sprite of the 2DRenderer, that still woudlnt show up, i had to actually assign the entire Sprite2DRenderer and not just the Sprite2DRenderer.sprite


    After re-reading this, now that iv been awake for a few hours. You seem to of stated you have the sprite graphic assigned on an Entity field. Which im un-able to do

    i was able to get the sprite to assign to the entity field by doing this
    rider64_2019-06-21_15-33-47.png
    But when i assign that to my created entities Sprite2DRenderer, nothing shows up still

    Code (CSharp):
    1.  
    2.             Entity tailGraphic = new Entity();
    3.             Entities.ForEach((Entity entity, ref SnakeHead snake, ref Translation transform) =>
    4.             {
    5.                 float3 foodTransform = new float3();
    6.                 float3 snakeTransform = new float3();
    7.                 snakeTransform = transform.Value;
    8.                 snakeTailToSpawn = snake.SnakeTail;
    9.                 tailGraphic = snake.Sprite;
    10.                 Entities.ForEach((Entity foodEntity, ref Translation foodTrans, ref FoodTag foodTag) =>
    11.                     {
    12.                         foodTransform = foodTrans.Value;
    13.                         if (math.distance(snakeTransform, foodTransform) < 1)
    14.                         {
    15.                             shouldSpawn = true;
    16.                             foodTag.ShouldMove = true;
    17.                         }
    18.                     });
    19.             });
    20.            if(!shouldSpawn)
    21.                    return;
    22.            Entity tailSegment = EntityManager.CreateEntity(typeof(Parent), typeof(Sprite2DRenderer), typeof(Translation), typeof(Rotation),
    23.  typeof(NonUniformScale), typeof(LayerSorting), typeof(SnakeTail));
    24.          
    25.             Translation translation = EntityManager.GetComponentData<Translation>tailSegment);
    26.              translation.Value = float3.zero;
    27.              EntityManager.SetComponentData(tailSegment, translation);
    28.          
    29.              Sprite2DRenderer renderer =
    30.              EntityManager.GetComponentData<Sprite2DRenderer>(tailSegment);
    31.              renderer.sprite = tailGraphic;
    32.              EntityManager.SetComponentData(tailSegment, renderer);
     
    Last edited: Jun 21, 2019
  13. Dunk86

    Dunk86

    Joined:
    May 10, 2015
    Posts:
    53
    @sniffle63 Perhaps there's something else going on (maybe check the scale?) - but yes, my sprite Entity is used directly and looks like:
    [EntityWithComponents(typeof(Sprite2D))]
    public Entity Sprite;


    EDIT: Also, what the hell, after fixing a compile error my scene has managed to forget about all my custom IComponentData references and data, so I need to re-setup everything....... Maaaaybe I should wait till the next patch (or just do everything in code since I can't trust the scene/inspector)
     
    Last edited: Jun 22, 2019
  14. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    363

    I thought it might of been that also, but alas it wasnt. No clue why it isnt working. Guess ill just go back to loading in scenes :/

    rider64_2019-06-22_13-47-15.png
    rider64_2019-06-22_13-47-34.png
    Unity_2019-06-22_13-48-53.png

    The image is just a black square, so technically i could just not use an image and it would display a black square. But thats not rly what i want to do


    *Edit*
    Also that suckssssssssssssssssssssssssssssssss, man that would be annoying