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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Resolved LocalTransform updates not being applied to Game or Scene views

Discussion in 'Entity Component System' started by Naewulf, Aug 9, 2023.

  1. Naewulf

    Naewulf

    Joined:
    Jun 17, 2019
    Posts:
    23
    So, I have this code:
    Code (CSharp):
    1. public struct MovementComponent : IComponentData
    2. {
    3.     public Entity Entity;
    4.  
    5.     public float Speed;
    6.     public Vector3 Direction;
    7. }
    8.  
    9. [BurstCompile]
    10. public partial struct MovementSystem : ISystem
    11. {
    12.     [BurstCompile]
    13.     public readonly void OnUpdate(ref SystemState state)
    14.     {
    15.         foreach (var (transform, movement) in SystemAPI.Query<RefRW<LocalTransform>, RefRO<MovementComponent>>())
    16.         {
    17.             transform.ValueRW = transform.ValueRO.Translate(movement.ValueRO.Speed * SystemAPI.Time.DeltaTime * movement.ValueRO.Direction.normalized);
    18.         }
    19.     }
    20. }
    I have entities that correspond to that query, and I can see their Position being updated in the inspector, as if they are moving, but they are not.

    If I manually alter in the inspector the LocalTransform Position, or the LocalToWorld matrix, the objects move correctly, but somehow the automatic System updates to the LocalTransform are not being applied to the entities.

    I noticed in the inspector that the LocalToWorld matrix is also not being automatically updated, only the Position of the LocalTransform is. Not sure if this is the expected behaviour, but like I said, changing this matrix manually also does make the entity move as expected.

    I've also tried to force my System to run before the TransformSystemGroup, and after it, and nothing changes either way.

    I'm sure it's some simple detail that I'm missing. If anyone can help me with that it will be of great help to me.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,986
    If I had to guess, there is some other component on your entity that isn't in the Unity Transforms namespace but has the attribute [WriteGroup(typeof(LocalToWorld))]. Unity Physics is a common culprit.
     
  3. Naewulf

    Naewulf

    Joined:
    Jun 17, 2019
    Posts:
    23
    This is the full code of my "MovementAuthoring.cs":
    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Entities;
    3. using Unity.Transforms;
    4. using UnityEngine;
    5.  
    6. public class MovementAuthoring : MonoBehaviour
    7. {
    8.     public float Speed = 10;
    9.     public Vector3 Direction = Vector3.zero;
    10. }
    11.  
    12. public class MovementBaker : Baker<MovementAuthoring>
    13. {
    14.     public override void Bake(MovementAuthoring authoring)
    15.     {
    16.         var entity = GetEntity(TransformUsageFlags.Dynamic);
    17.  
    18.         AddComponent(entity, new MovementComponent
    19.         {
    20.             Entity = entity,
    21.  
    22.             Speed = authoring.Speed,
    23.             Direction = authoring.Direction
    24.         });
    25.     }
    26. }
    27.  
    28. public struct MovementComponent : IComponentData
    29. {
    30.     public Entity Entity;
    31.  
    32.     public float Speed;
    33.     public Vector3 Direction;
    34. }
    35.  
    36. [BurstCompile]
    37. public partial struct MovementSystem : ISystem
    38. {
    39.     [BurstCompile]
    40.     public readonly void OnUpdate(ref SystemState state)
    41.     {
    42.         foreach (var (transform, movement) in SystemAPI.Query<RefRW<LocalTransform>, RefRO<MovementComponent>>())
    43.         {
    44.             transform.ValueRW = transform.ValueRO.Translate(movement.ValueRO.Speed * SystemAPI.Time.DeltaTime * movement.ValueRO.Direction.normalized);
    45.         }
    46.     }
    47. }
    I just created a normal 3D cube, added that component, and this is what it looks like:

    upload_2023-8-9_14-7-32.png

    There are no other files present. Brand new project. The Cube has 3 empty GameObject children that will serve as spawn points when I get this thing moving properly:

    upload_2023-8-9_14-9-36.png

    Pretty weird.
     

    Attached Files:

  4. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    825
    Is the subscene open and set to authoring data in your Preferences>Entities>Scene view mode? if you change it to runtime/and/or close the subscene do things appear correctly?
     
  5. Naewulf

    Naewulf

    Joined:
    Jun 17, 2019
    Posts:
    23
    Scene view mode is "Runtime Data". I can see the 3D cube in both Game AND Scene tabs, and if I manually change the value of the position in the inspector it moves properly in both tabs.

    The problem is that my System is updating its position programatically and only in this case things do not move.

    upload_2023-8-9_16-25-31.png

    The image above shows the X position of the Cube being set incrementally through my System (currently at 165.7683) and as you can see, the cube is in the middle of the Game tab.

    Note that the Local To World matrix has the value of 0 for the X of its last line.

    Now, if I manually alter the Position of the Local Transform through the inspector, the result is like the image below, in which you can see that the Local To World matrix is correctly updated and the Cube goes from 0 (X axis) to 9.5 (X axis), which is the value I have set manually.

    upload_2023-8-9_16-31-16.png

    In fewer words: when the ISystem changes the Position of the Local Transform, the Local To World matrix does not get recalculated, so the object does not really move, but if I set some value for the Position of the Local Transform manually from the inspector, the Local To World matrix does get updated automatically and the object goes to its new position as expected.
     
  6. Naewulf

    Naewulf

    Joined:
    Jun 17, 2019
    Posts:
    23
    For future reference, you can't use readonly with the OnUpdate method, so I removed "readonly" from the following line:
    Code (CSharp):
    1. public readonly void OnUpdate(ref SystemState state)
    No idea how it got there though, but it is what it is.