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

Resolved How to set world position of provisional entity (ecb.Instantiate)?

Discussion in 'Entity Component System' started by OUTTAHERE, Mar 12, 2023.

  1. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    ... in fact, how to set the world position of anything without going through TransformAspect?
    upload_2023-3-12_17-14-2.png
    This does not work, ships end up at 0,0,0, they should end up 160-200 units away from origin.

    This works fine if I forego the ECB and use TransformAspect directly (can't get TransformAspect of a provisional entity), but writing WorldTransform alone does not seem to work. This is [UpdateInGroup(typeof(InitializationSystemGroup))], too, so physics copying or something shouldn't interfere, right?

    I tried this with LocalTransform instead, that also does not work.

    PS: I am aware of the ECS RandomSpawn sample, but I need to understand why setting the component doesn't work here; and also scheduling a job for this feels quite off (but is a great tool once this becomes fully procgen population of the game world - current system is a test system only)
     
    Last edited: Mar 12, 2023
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    WorldTransform is not for user writing but only reading. You should use LocalTransform for that (and data from parent if you have hierarchy, or ParentTransform which is storing parent WorldTransform)
    upload_2023-3-12_21-3-39.png
     
  3. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    Thanks. However, Local Transform also doesn't work in my example.
    upload_2023-3-12_19-14-36.png
    In fact, it gets weirder, the component is set, but LocalToWorld still reflects the old world transform.

    Decorating the system with either
    [WriteGroup(typeof(LocalTransform)]
    [WriteGroup(typeof(LocalToWorld)]
    [WriteGroup(typeof(WorldTransform)] or
    [WriteGroup(typeof(TransformAspect)]

    doesn't work.
     
    Last edited: Mar 12, 2023
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    It definitely works, show full code
     
  5. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    Thank you for looking into it. Code:

    Code (CSharp):
    1. using Jovian.Components;
    2. using Sisus.Debugging;
    3. using Unity.Collections;
    4. using Unity.Entities;
    5. using Unity.Mathematics;
    6. using Unity.Physics;
    7. using Unity.Rendering;
    8. using Unity.Transforms;
    9. using Random = UnityEngine.Random;
    10.  
    11. namespace Jovian
    12. {
    13.     [RequireMatchingQueriesForUpdate]
    14.     [UpdateInGroup(typeof(InitializationSystemGroup))]
    15.     public partial struct VesselSpawningSystem : ISystem
    16.     {
    17.         private EntityQuery _bubbles;
    18.  
    19.         public void OnCreate(ref SystemState state)
    20.         {
    21.             _bubbles = state.EntityManager.CreateEntityQuery(typeof(Bubble), typeof(TagRequestSpawn));
    22.             state.RequireForUpdate<ShipRegistryElement>();
    23.             state.RequireForUpdate<TagRequestSpawn>();
    24.         }
    25.  
    26.         public void OnDestroy(ref SystemState state)
    27.         {
    28.             _bubbles.Dispose();
    29.         }
    30.      
    31.         public void OnUpdate(ref SystemState state)
    32.         {
    33.             var rolling = 0;
    34.             var ecb = new EntityCommandBuffer(Allocator.Temp);
    35.          
    36.             var registry = SystemAPI.GetSingletonBuffer<ShipRegistryElement>();
    37.             foreach (var bubble in SystemAPI.Query<Bubble>().WithAll<TagRequestSpawn>())
    38.             {
    39.                 for (var i = 0; i < 10; i++)
    40.                 {
    41.                     var ship = ecb.Instantiate(registry[rolling++ % registry.Length].prefabs);
    42.                     var transform = LocalTransform.FromPositionRotation(
    43.                         Random.onUnitSphere * Random.Range(160, 200),
    44.                         quaternion.identity);
    45.                     ecb.SetComponent(ship, transform);
    46.  
    47.                     //ecb.SetComponentForLinkedEntityGroup(ship, WTFisaMASK, new ReqBubbleEntry {root = bubble});
    48.  
    49.                     //Important, so freshly spawned ships do not leak into the void world (or are rendered)
    50.                     ecb.RemoveComponent<PhysicsWorldIndex>(ship);
    51.                     ecb.AddComponent<DisableRendering>(ship);
    52.                 }
    53.  
    54.                 //all bubble requests have been processes, remove them all.
    55.                 ecb.RemoveComponent<TagRequestSpawn>(bubble.root);
    56.                 Dev.Log($"Spawning {rolling} ships in {bubble.root}");
    57.             }
    58.  
    59.             ecb.Playback(state.EntityManager);
    60.             ecb.Dispose();
    61.         }
    62.     }
    63.  
    64.     public struct TagRequestSpawn : IComponentData
    65.     {
    66.     }
    67. }
    68.  
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Well, you’re using physics (we don’t use that since the beginning) can’t say much about how it affects stuff these days in 1.0. Out of curiosity - where entity will appear if you comment lines 50 and 51?
     
  7. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Also, it’s a parent itself right?
     
  8. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    Yes, but there's only a UI positioned entity inside.
    I suspect it's this.
    upload_2023-3-12_19-47-42.png
    Something, likely DisableRendering, causes LocalToWorld from being updated. Which is both sensible and insensible. The combined Matrix is used by a UI system I use to "see" the invisible entities.
     
  9. suity447

    suity447

    Joined:
    Oct 18, 2022
    Posts:
    33
    I also suspect that disabling the rendering will affect the LocalToWorld
     
  10. Quit

    Quit

    Joined:
    Mar 5, 2013
    Posts:
    63
    Oddly enough WorldTransform doesn't seem to work properly, especially when physics get involved. Documentation says it's reflecting one thing, but on my side it doesn't even update. I've mentioned that here - https://forum.unity.com/threads/worldtransform-doesnt-change-on-child-entity.1409133/.

    There are quite a few basic things not working properly. Sometimes I question if it's actually a bug or some kind of a feature, cuz it's so basic - it should work day 1.
     
  11. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    I'm refactoring my system of child entities to something that spawns an entirely unrelated set of entities for UI representation, and then establishes links itself.

    Those Unity structures (parent/child, linkedentitygroup, etc.) are just too opaque and unreliable for someone not knowing them inside out.
     
  12. HomeLabourer

    HomeLabourer

    Joined:
    Jul 11, 2022
    Posts:
    3
    Spawning an entity with physcis and set its position by setting WorldTransform and LocalTransform at the same time between FixedStepSimulationGroup and TransformSystemGroup solved this problem.

    WorldTransform.position = LocalTransform.position = desirePosition;