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

Bug TransformAspect bug

Discussion in 'Entity Component System' started by Zimaell, Mar 25, 2023.

  1. Zimaell

    Zimaell

    Joined:
    May 7, 2020
    Posts:
    345
    wrote the first code of their cube example

    https://github.com/Unity-Technologi...er/EntitiesSamples/EntitiesTutorial/README.md

    and got an error immediately, although I tried the same example a week ago and it worked

    Code (CSharp):
    1. foreach (var transform in SystemAPI.Query<TransformAspect>())
    Assets\Scripts\Entity\TurretRotationSystem.cs(10,1): error SGICE002: This error indicates a bug in the DOTS source generators. We'd appreciate a bug report (Help -> Report a Bug...). Thanks! Error message: 'System.IndexOutOfRangeException: Index was outside the bounds of the array. |--| at System.Collections.Immutable.ImmutableArray`1.get_Item(Int32 index) |--| at Unity.Entities.SourceGen.SystemGenerator.SystemAPI.Query.IdiomaticCSharpForEachDescription.<TryGetQueryDatas>g__TryGetIdiomaticCSharpForEachQueryType|70_0(ITypeSymbol typeSymbol, Location errorLocation) |--| at Unity.Entities.SourceGen.SystemGenerator.SystemAPI.Query.IdiomaticCSharpForEachDescription.TryGetQueryDatas(ICollection`1& queryTypes) |--| at Unity.Entities.SourceGen.SystemGenerator.SystemAPI.Query.IdiomaticCSharpForEachDescription..ctor(SystemDescription systemDescription, QueryCandidate queryCandidate, Int32 numForEachsPreviouslySeenInSystem) |--| at Unity.Entities.SourceGen.SystemGenerator.SystemAPI.Query.IdiomaticCSharpForEachModule.RegisterChangesInSystem(SystemDescription systemDescription) |--| at Unity.Entities.SourceGen.SystemGenerator.SystemGenerator.Execute(GeneratorExecutionContext context)'

    Assets\Scripts\Entity\TurretRotationSystem.cs(35,51): error CS0246: The type or namespace name 'TransformAspect' could not be found (are you missing a using directive or an assembly reference?)

    Entities 1.0.0-pre.65
    Entities Graphics 1.0.0-pre.65

    am i missing something?

    Add: page TransformAspect missing
    https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/transform-aspect.html

    Sorry... that page seems to be missing!

    The page you are looking for might have been renamed, moved, or deleted.
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,655
    TransformAspect is removed since pre.65
     
    Zimaell likes this.
  3. Zimaell

    Zimaell

    Joined:
    May 7, 2020
    Posts:
    345
    what was it replaced with? what to use now?
     
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,655
    Zimaell likes this.
  5. Zimaell

    Zimaell

    Joined:
    May 7, 2020
    Posts:
    345
    Thank you.
     
  6. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    715
    Just a little more information since the 0.51 to 1.0 upgrade guide makes no mention of TransformAspect or how to replace it.

    So apparently TransformAspect was introduced in 1.0.0-exp.8. Then in 1.0.0-pre.65 it was removed.
    The changelog says this:
    "The TransformAspect struct was removed. Recent changes to the Entities transform systems made the current implementation of TransformAspect much less useful, and we've decided to remove it from the package until we can provide a more valuable abstraction over the DOTS transform components."

    So I take that to mean - use LocalTransform instead.

    Additionally, at some point there was a WorldTransform but I'm not sure when it was introduced, and it was removed at some point (I think between pre.47 and pre.65). I think maybe to get the world transform you can do LocalTransform.ComputeWorldTransformMatrix() ? EDIT: The LocalToWorld component can be used instead.
     
    Last edited: Apr 5, 2023
    MatanYamin likes this.
  7. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    177
    LocalToWorld component can be used.
     
    lclemens likes this.
  8. thurd666

    thurd666

    Joined:
    May 12, 2022
    Posts:
    7
    How? It seems to be Read Only...

    This is just inexcusable by the Unity team. Introduce a function to address entity position (pretty fundamental I'd say) and then brake it a few weeks later and offering no replacement, no explanation, NOTHING. Every Youtube tutorial I've found is already so outdated regarding ECS that you're on your own and since documentation also doesn't keep up and offers no help regarding most basic concepts we're all just blind here...
     
    LiThuaniaSystems and MatanYamin like this.
  9. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    177
    Yes, it is. If you need to move an entity you should use LocalTransform component. It represents world position of entity if no parent exists for this entity. Otherwise, if you need to set world position, you should take into account parent position and calculate entity position relative to it.

    Don't blindly follow youtube tutorials. Read official documentation more.
     
  10. thurd666

    thurd666

    Joined:
    May 12, 2022
    Posts:
    7
    I've been trying to read the documentation but there is barely any information in it. Right now I'm still working on a "proper" (performance wise) way of creating Entities and placing them where I need to but the docs don't help at all.

    Look at this problem with SetComponentData. In documentation there is just one line "Sets the value of a component of an entity." with a bunch of metadata regarding it's parameters.
    But if I use it in my function inside a System:
    Code (CSharp):
    1.  protected override void OnUpdate()
    2.     {
    3.         EntityQuery asteroidEntityQuery = EntityManager.CreateEntityQuery(typeof(AsteroidTag));
    4.         AsteroidSpawnerComponent asteroidGeneratorComponent = SystemAPI.GetSingleton<AsteroidSpawnerComponent>();
    5.  
    6.         int spawnAmount = 40;
    7.  
    8.         if (asteroidEntityQuery.CalculateEntityCount() < spawnAmount)
    9.         {
    10.             NativeArray<Entity> asteroidArray = EntityManager.Instantiate(asteroidGeneratorComponent.asteroidPrefab, spawnAmount, Allocator.Temp);
    11.                    
    12.             foreach (Entity entity in asteroidArray)
    13.             {
    14.                 EntityManager.SetComponentData(entity,
    15.                     new LocalTransform
    16.                     {
    17.                         Position = new Vector3(1001, 500, 1002)
    18.                     });
    19.             }
    20.            
    21.             asteroidArray.Dispose();
    22.         }
    23.     }
    my Entities stop being rendered during Play. They are instantiated properly, they even have the proper Position that I'm assigning here, but they stop rendering and rotating (done by a different System). If I remove this whole foreach my Entities render fine and rotate properly but are bound to the position of the Prefab I'm using.

    I know I'm a beginner here, I really do. But quirks like this should be explained. There should be examples of how to do the most obvious tasks in ECS and properly assigning a Position to an Entity is one of them.
     
  11. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    291
    You're not setting the Scale in the LocalTransform. It will be 0 (default for a float in C#). Same with the Rotation field.
     
    thurd666 and elliotc-unity like this.
  12. thurd666

    thurd666

    Joined:
    May 12, 2022
    Posts:
    7
    Thank you, that worked. But I still don't understand why it works like that. If I'm using a Prefab which already has set parameters I'd assume I only have to explicitly change those that really need changing. Why would I need to declare things I've already setup the Prefab for? It's not intuitive at all.

    But the worst part is, this is exactly the kind of behavior that should be explained in SetComponentData documentation.
     
  13. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    291
    If it’s not explained, it’s probably because it’s the kind of thing that doesn’t need explaining for the average C# developer. You’re setting a whole struct, not just some of its fields, because you’re passing in a new instance of the struct entirely (hence the “new” keyword). Barring some strange possible designs such as nullable fields (a bad idea and merely illustrative) or some source generation mechanism that entirely changes the semantics of the written code, there’s no way for the library code to know that you only want to set one field. However, such a task is available in one of two ways. You can read, modify, and set a component. This seems clunky, but it generally works and is basically all you can do if you can’t apply the following case. The other way, applicable in some cases (with a ComponentLookup, and not with an EntityManager since that does not currently allow byref to a general Entity) is to set fields of a ref to a component in-place.

    Again, with the semantics of passing a component in its entirety to SetComponentData, it should not be a surprise that everything in it must be set correctly, as you are replacing the entire component. LocalTransform includes a number of helper static methods to set up a valid (in terms of being a typical transform) transform with defaults when necessary, such as FromPosition that sets scale 1 / identity rotation and FromPositionRotation that sets scale 1.
    https://docs.unity3d.com/Packages/com.unity.entities@1.0/api/Unity.Transforms.LocalTransform.html
     
    thurd666 likes this.