Search Unity

Official Exciting developments in upcoming Entities 1.0 releases

Discussion in 'Entity Component System' started by jivalenzuela, Sep 26, 2022.

  1. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    Howdy. I'm Joe Valenzuela from the DOTS team. We've been hard at work making changes in both the Unity Editor and various packages as part of our initial Entities 1.0 experimental release. There are all sorts of bug fixes, optimizations, and new APIs that we think will allow Unity developers to make their games more ambitious, more performant and, in general, more awesome.

    Thanks to everyone who used these packages in preview and provided feedback in the forums or elsewhere - our experimental 1.0 release has relied on your insights and efforts. As part of that process we’ve taken a careful look at our existing APIs and in some cases decided to deprecate, rename, or remove types and functions. We’ll have a detailed upgrade guide for folks who have been following along with Entities before full release, but in the meantime I wanted to show off some things I think are cool about the experimental release.

    Conversion -> Baking
    Conversion has been the heart of the Entities data pipeline. In the 1.0 experimental release, we’ve reengineered it to the point where we decided it needed a new name: Baking.

    In the old Conversion system, component data is authored in the familiar Unity environment you know and love, and data is converted from this to a fast, memory-ready format either at run-time (via ConvertToEntity) or at Editor time (by virtue of being in a Subscenes).

    In Baking, you still author data in the Unity Editor and get fast, memory-ready binary data at runtime, but the mechanism is substantially different. We’ve split the process into a two-pass system in order to do the most expensive processing with ECS, so it’s faster. The dependency tracking is precise, deterministic, and robust, meaning you only update the data that’s changed, which improves live update with open subscenes. And the code itself is simpler and easier to understand, and as a consequence has fewer bugs and edge cases. The API is safer as well, making it harder to make mistakes (and simpler as well, we think, but that’s for you to decide!).

    Here’s a small example of the API:

    Code (CSharp):
    1. public class SelfDestructAuthoring : MonoBehaviour
    2. {
    3.     public float TimeToLive;
    4.  
    5.     class Baker : Baker<SelfDestructAuthoring>
    6.     {
    7.         public override void Bake(SelfDestructAuthoring authoring)
    8.         {
    9.  
    10.             AddComponent(new SelfDestruct {TimeToLive = authoring.TimeToLive});
    11.         }
    12.     }
    13. }
    One thing developers should be aware of ahead of time is that we’ll be deprecating runtime conversion - like ConvertToEntity - and removing it before our full 1.0 release. We know this is a commonly used feature, but runtime conversion has been a constant source of bugs (because it requires maintaining a separate pipeline for moving authoring data around) and isn’t possible to maintain with our goal of keeping editor functionality out of the DOTS runtime. Thankfully, runtime conversion is (almost) never necessary, and in the few cases it is, the subset of functionality needed is straightforward enough to support on the client side.


    Build Configs
    Standalone builds previously required the use of Build Configuration Assets and the separate “build config” menu options.


    This will no longer be the way of building standalone projects using DOTS.

    Having a completely separate build tool allowed us to rapidly prototype configuration options for DOTS, and it’s necessary for some work we’re doing unrelated to Entities 1.0. But having a different way of making standalone builds was a frequent source of confusion for new users, and consolidating build systems is not possible in any reasonable timeframe. While we think Build Configs may be a great solution someday, they aren’t strictly necessary today, and we want to prioritize the simple solution that works for almost every case. So we’ve made the classic Unity build page work for the vast majority of cases. Developers who need more specialized build configuration can use the Scriptable Build Pipeline, a powerful API for building content.

    Build Configs will still operate as usual in the experimental build, and building with the classic Unity build window will be available as a toggle-able option (currently Preferences -> Entities -> Builtin Builds Enabled, but subject to change). By release we plan to make building via the build window the default.

    Transforms
    While developing Entities, we gradually realized that Transforms - the components and related systems that maintain an object’s position, orientation, and hierarchy - needed revision. Based on our own experience and those of our partners, we’re rolling out a substantially improved API and backend. In addition we’re taking the opportunity to prevent errors by precluding the use of features at runtime that are difficult or impossible to support well, like non-uniform scale (non-uniform scale for static data is handled at Bake time, and we have special case path to allow some common uses of non-uniform scale).

    There are some finishing touches we have to put on before fully switching over to the new Transform system, but when we're done I think you'll find...

    It’s simpler.

    Transforms are now baked from the GameObject Transform down to a wafer thin Entity representation of only 8 floats. The Entity component, in turn, is transformed by fewer systems in a more streamlined fashion, using fewer systems, and operating on less data.

    It’s cheaper.

    Gameplay code frequently deals with rotation and position. Previously, transforms were based completely on matrices, making extracting rotation expensive (at best). Now we maintain data in its quaternion form, the format in which it’s most often used.

    It’s robust.

    Our previous Transform data protocol had 15 different component types, some of which were very infrequently used, but all had to be supported. The new data protocol is substantially smaller and easier to support.

    It’s more correct.

    The previous Transform data protocol didn’t put any real world constraints on what was feasible in game code - literally just offering a matrix - so every system made up its own rules on what it could handle. This can lead to unintuitive errors as systems ignore features of the provided transform (like non-uniform scale).

    idiomatic foreach
    When Entities.ForEach was introduced, it was the quick and easy alternative to writing full-blown job code. However, the fullness of time revealed some limitations. The biggest problem was that nested loops were impossible, making it cumbersome to model many typical solutions. And after the introduction of IJobEntity, the barrier to jobified code was now no longer as steep, so we went back to the drawing board to express the most common remaining use case for Entities.ForEach - main thread immediate code - using more natural C# syntax. We call the mechanism idiomatic foreach.

    Code (CSharp):
    1. foreach (var (rotateAspect, speedModifierRef) in
    2.                 SystemAPI.Query<RotateAspect, RefRO<SpeedModifier>>())
    3.      rotateAspect.Rotate(time, speedModifierRef.ValueRO.Value);

    The biggest takeaway is that there are fewer edge-cases where APIs that work outside of a loop don't work inside, and there’s some behind-the-scenes improvements as well. Entities.ForEach remains in 1.0, but we’re strongly encouraging folks to use idiomatic foreach and jobs instead. To that end, we’re not supporting Entities.ForEach in ISystem (it will remain in SystemBase) and plan to phase out support post 1.0.

    Aspects
    One of the most obvious new API features is the introduction of Aspects. Aspects offer a view on commonly used data (like translation and rotation) along with methods in order to provide a low-cost, fully-burstable interface. This allows developers to write code against an Aspect without coupling themselves to irrelevant implementation details. You can also write your own Aspects to make your code easier to use correctly.

    Here’s a simple example to keep something oriented toward another entity’s position. The code is straightforward, but requires us to query both the Translation and Rotation component. If one of these became redundant (unlikely in this case, but stay with me) you’d have to audit every query to make sure you were using the minimal set of parameters or else you’d be introducing superfluous dependencies. (Small note - currently Aspects will pull in dependencies for all contained components whether they are used at the call site or not, so there’s room for performance improvement in future releases).

    Code (CSharp):
    1. public partial struct LookJob : IJobEntity
    2. {
    3.     [ReadOnly]
    4.     public ComponentLookup<Translation> lookup;
    5.  
    6.     public void Execute(ref Rotation r, in Translation t, in LookAt_RotationTranslation lookAt)
    7.     {
    8.         float3 head = lookup[lookAt.Other].Value;
    9.         float3 forward = new float3(head.x - t.Value.x, t.Value.y, head.z - t.Value.z);
    10.  
    11.         r.Value = quaternion.LookRotation(forward, math.up());
    12.     }
    13. }
    14.  
    15. protected override void OnUpdate() {
    16.     new LookJob{lookup=GetComponentLookup<Translation>(true)}.Schedule();
    17. }
    18.  
    With the TransformAspect, the specific mechanism used to encode position and orientation are kept up to date. Write your API against the aspect and it’s trivial to keep up to date. And best of all, we use the same query mechanisms behind the scenes, so you still get performance by default.

    Code (CSharp):
    1. public partial struct LookJob : IJobEntity
    2. {
    3.     [NativeDisableContainerSafetyRestriction]
    4.     [ReadOnly]
    5.     public ComponentLookup<Translation> lookup;
    6.  
    7.     public void Execute(ref TransformAspect ta, in LookAt_TransformAspect lookAt)
    8.     {
    9.         float3 otherPosition = lookup[lookAt.Other].Value;
    10.  
    11.         ta.LookAt(otherPosition, math.up());
    12.     }
    13. }
    14.  
    15. protected override void OnUpdate() {
    16.     new LookJob{lookup=GetComponentLookup<Translation>(true)}.Schedule();
    17. }

    We’re providing two Aspect interfaces to start - TransformAspect and RigidBodyAspect - and are looking forward to hearing your feedback on the feature.

    Enableable Components
    One of the most far-reaching changes we did was to introduce the concept of Enableable components. Previously, if you wanted to exclude a set of entities in the same Archetype from a query, you’d have to either group them with SharedComponent filters or change their Archetype by adding and removing tag components. Both options require expensive structural changes, and increase memory fragmentation. Furthermore, neither operation can be performed immediately from job code; the desired operations must be recorded into an EntityCommandBuffer and played back later in the frame, leaving the entity in a potentially inconsistent state in the meantime.

    Enableable components can be efficiently enabled and disabled at runtime without triggering a structural change (even from job code running on a worker thread). A similar effect can already be achieved with a component containing a one-byte “isEnabled” field, but enableable components are a first-class feature of the Entities package, fully supported by EntityQuery and Entities job types. Disabling a component on an entity prevents that entity from matching a query that requires the component, which means that jobs running against this query will automatically skip the entity as well. SIMD-optimized query-matching and chunk-iteration code keeps the overhead of skipping disabled components to a minimum. Enableable tag components are ideal for high-frequency state changes, without increasing the number of unique archetype permutations. In our tests, toggling enableable components from a parallel job runs 9x faster than adding/removing the same components using structural changes.

    Code (CSharp):
    1. public struct TargetEnableable : IComponentData, IEnableableComponent
    2. {
    3.     public float3 target;
    4. }
    5.  
    6. // ...
    7. var archetype = m_Manager.CreateArchetype(typeof(EcsTestData), typeof(TargetEnableable));
    8. var entities = m_Manager.CreateEntity(archetype, 1024, World.UpdateAllocator.ToAllocator);
    9.  
    10. EntityQuery query = GetEntityQuery(typeof(TargetEnableable));
    11.  
    12. // Disable the target on one of the entities.
    13. // entities[4] will now be excluded from the query.
    14. m_Manager.SetComponentEnabled<TargetEnableable>(entities[4], false);
    15.  
    16. int fooCount = query.CalculateEntityCount(); // returns 1023

    ISystem & IJobEntity
    While they aren’t new in 1.0, we’ve added support throughout Entities packages to make ISystem and IJobEntity more useful than ever.

    ISystem is an interface implemented by unmanaged component systems. It’s specially designed to keep you on the fast path using Burst and away from C# managed memory, which introduces garbage collection. Support has been added throughout Entities (and other packages) to keep us on the fast path as much as possible.

    While it can’t write your code for you, It’s never been more straightforward to stick to the “high performance” subset of C# (HPC#) that unlocks next-gen performance.

    Code (CSharp):
    1. [BurstCompile]
    2. public partial struct TheFriendlyOgreSystem : ISystem
    3. {
    4.   // Store reference to a friendly ogre entity
    5.   Entity friendlyOgreEntity;
    6.  
    7.   [BurstCompile]
    8.   public void OnCreate(ref SystemState state)
    9.   {
    10.     // Create a temporary ComponentType NativeArray.
    11.     using var friendlyOgreComponentTypes =
    12.     new FixedList64Bytes<ComponentType>
    13.     {
    14.       ComponentType.ReadWrite<HealthData>(),
    15.       ComponentType.ReadWrite<AliveTag>()
    16.     }.ToNativeArray(Allocator.Temp);
    17.  
    18.     // Create an Entity of Archetype (HealthData, ShieldData)
    19.     var friendlyOgreArchetype = state.EntityManager.CreateArchetype(friendlyOgreComponentTypes);
    20.     friendlyOgreEntity = state.EntityManager.CreateEntity(friendlyOgreArchetype);
    21.   }
    22.  
    23.   public void OnDestroy(ref SystemState state) {}
    24.  
    25.   [BurstCompile]
    26.   public void OnUpdate(ref SystemState state)
    27.   {
    28.     // Check if the friendly ogre is alive
    29.     if (state.EntityManager.IsComponentEnabled<AliveTag>(friendlyOgreEntity))
    30.     {
    31.       // Get HealthData of the friendly ogre. and kill it over time. (10HP per second)
    32.       var healthData = SystemAPI.GetComponent<HealthData>(friendlyOgreEntity);
    33.       healthData.Left -= 10f*SystemAPI.Time.DeltaTime;
    34.       if (healthData.Left > 0)
    35.         SystemAPI.SetComponent(friendlyOgreEntity, healthData);
    36.       else
    37.         state.EntityManager.SetComponentEnabled<AliveTag>(friendlyOgreEntity, false);
    38.     }
    39.   }
    40. }
    Part of this effort has gone into making it easier to move code from the main thread to a job, or from your update to a utility function, or from a SystemBase system to an ISystem one.

    In part because of this expanded support, IJobEntity is now the recommended job type to use when convenience is desired.


    Code (CSharp):
    1. partial struct UpdateChunkBoundsJob : IJobEntity
    2. {
    3.     [ReadOnly]
    4.     public ComponentTypeHandle<BoundsComponent> ChunkComponentTypeHandle;
    5.  
    6.     void Execute(ref ChunkBoundsComponent chunkBounds, in ChunkHeader chunkHeader)
    7.     {
    8.         var curBounds = new ChunkBoundsComponent
    9.                         {
    10.                           boundsMin = new float3(1000, 1000, 1000),
    11.                           boundsMax = new float3(-1000, -1000, -1000)
    12.                         };
    13.         var boundsChunk = chunkHeader.ArchetypeChunk;
    14.         var bounds = boundsChunk.GetNativeArray(ChunkComponentTypeHandle);
    15.         for (int j = 0; j < bounds.Length; ++j)
    16.         {
    17.             curBounds.boundsMin = math.min(curBounds.boundsMin,
    18.                                            bounds[j].boundsMin);
    19.             curBounds.boundsMax = math.max(curBounds.boundsMax,
    20.                                            bounds[j].boundsMax);
    21.         }
    22.  
    23.         chunkBounds = curBounds;
    24.     }
    25. }


    But wait there’s more!
    There’s a lot to look forward to in Entities 1.0 (some of these code samples include “sneak previews” of other changes we’ll be discussing in upcoming posts) and we’re all looking forward to finally getting our work in front of y'all. While we’re proud of the work we’re doing, the real payoff is seeing what all the incredible Unity developers do with it. Thanks for reading and we will keep you posted for more detail as we approach the official release of Entities 1.0!
     
    Last edited: Oct 3, 2022
  2. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Hi @jivalenzuela

    Thanks for this post :)

    - Can you explain more how can we scale entity non-uniformly in new transform system?
    - Can we use ComponentLookup outside of Job?
     
  3. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Based on known bugs in this topic I have one question:

    Why you try to regenerate user code? Why not just generate new code that can be called manually so we can write whatever we want and never face bugs that our code can not be reconverted to some another form?

    Current bugs is exactly result of fail on trying to regenerate from user code.
    Can you stop doing this or provide or provide option to disable unity generation and write our own or support alternative way maybe something like this:
    Code (CSharp):
    1. // we write
    2.     [SgenECSJob, Schedule, AggresiveInlining]
    3.     private static void LookJob(ref TransformAspect ta, in LookAt_TransformAspect lookAt, in ComponentLookup<Translation> lookup )
    4.     {
    5.         float3 otherPosition = lookup[lookAt.Other].Value;
    6.         ta.LookAt(otherPosition, math.up());
    7.     }
    8.  
    9.     [SgenECSJob, Schedule, AggresiveInlining]
    10.     private static void MoveJob(ref TransformAspect ta, in Move_TransformAspect move )
    11.     {
    12.         ta.Move(move.amount);
    13.     }
    14.  
    15.     protected override void OnUpdate()
    16.     {
    17.         OnUpdate_SGen( );
    18.     }
    19.  
    20.     // Sgen Auto Generated
    21.     public partial struct LookJob_SGen : IJobEntity //there full implementation of job
    22.     {
    23.         [NativeDisableContainerSafetyRestriction]
    24.         [ReadOnly]
    25.         public ComponentLookup<Translation> lookup;
    26.  
    27.         private void Execute(ref TransformAspect ta, in LookAt_TransformAspect lookAt )
    28.         {
    29.             LookJob( ref TransformAspect ta, in LookAt_TransformAspect lookAt, in lookup );
    30.         }
    31.     }
    32.  
    33.     public partial struct MoveJob_SGen : IJobEntity //there full implementation of job
    34.     {
    35.         private void Execute(ref TransformAspect ta, in Move_TransformAspect move )
    36.         {
    37.             MoveJob( ref TransformAspect ta, in Move_TransformAspect move );
    38.         }
    39.     }
    40.  
    41.     protected override void OnUpdate_SGen()
    42.     {
    43.         new LookJob_SGen{lookup=GetComponentLookup<Translation>(true)}.Schedule();
    44.         new MoveJob_SGen{}.Schedule();
    45.     }
     
    Last edited: Sep 28, 2022
  4. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    A lot of this stuff was badly needed. I look forward to using the new Transforms.

    You may want to think about removing Entities.ForEach in SystemBase before 1.0. The reason I say this is because a lot of old tutorials use Entities.ForEach. Many new users are probably going to be using those old tutorials. If anything is going to force the rewriting of tutorials it will be the 1.0 release. I just think it makes sense to get the API stabilized at least as far as the fundaments are concerned before 1.0.
     
    UniqueCode, Arnold_2013 and JesOb like this.
  5. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Can you please make IsComponentEnabled return false for absent component instead of assert
    In this case we can use this API as replacement for Adding/Removeing tags without code rewrite
    and actually mix and match both approaches on per entity basis. Some entities disable component some just remove it.
     
  6. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    > Can you explain more how can we scale entity non-uniformly in new transform system?

    There's a post-transformation matrix you can use to apply arbitrary linear multiplies with your final LocalToWorld. They don't propagate hierarchically and won't be used by the Transform system.

    > Can we use ComponentLookup outside of Job?

    Yop!
     
    JesOb likes this.
  7. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    You may want to think about removing Entities.ForEach in SystemBase before 1.0. The reason I say this is because a lot of old tutorials use Entities.ForEach. Many new users are probably going to be using those old tutorials. If anything is going to force the rewriting of tutorials it will be the 1.0 release. I just think it makes sense to get the API stabilized at least as far as the fundaments are concerned before 1.0.​

    Thanks for the suggestion. It's been a hotly debated topic on the team, especially since 1.0 represents the best time to clean up the API. While we've got a lot of confidence in the replacements for Entities.ForEach, removing it in the anticipated timeframe is unlikely.
     
  8. Thermos

    Thermos

    Joined:
    Feb 23, 2015
    Posts:
    148
    Good to see Entities finally reached 1.0.

    If runtime conversion and ConvertToEntity are dead, then what's the best approch to dynamic load prefabs and convert it to an entity, pure or hybrid?

    So in 1.0 all pure entities must be placed inside a subscene? What about the hybrid entities? How to understand the memory usage and incremental updates if we put all our prefabs into a subscene? The release schedual of DOTS addressable?
     
    lclemens, Krooq and Opeth001 like this.
  9. officialfonee

    officialfonee

    Joined:
    May 22, 2018
    Posts:
    44
    ISystem allows easy access to main-threaded burst-compiled code however if we need burst-compiled code that is run outside a system, or doesn't need to act like a system, is there going to be an API that allows us to run some main-threaded burst-compiled code? Or is the official planned way to achieve this through the Burst FunctionPointers?
     
    Antypodish likes this.
  10. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Just put [BurstCompile] on a static function and its declaring type, and when you call it it should be the bursted version; this has worked for several burst versions now.
     
    DaxodeUnity and Antypodish like this.
  11. peaj_metric

    peaj_metric

    Joined:
    Sep 15, 2014
    Posts:
    146
    Great to see the experimental 1.0 version.
    Everything looks pretty solid.

    One sentence concerns me though:
    I am currently using a custom Addressable Entities implementation to load and convert the prefabs at runtime.
    I would love to replace this with a solution that converts the prefabs at edit time but so far this is not possible.
    Subscenes seem to be the only solution to properly convert game objects which really leaves a big gap on the assets/prefabs side.

    I really hope addressables for entities will fill this gap. Sad it didnt make it into the experimental release.
    Would be optimal to just swap my addressables with the official implementation to make it work.

    We are using a custom format for tile maps which are populated at runtime with tilesets loaded from prefabs.

    This hard cut between edit and runtime data might be problematic with tools used in game and in editor in general.
    E.g. when building a level editor there are only 2 options:
    1. Build 2 separate editors (One for the Unity Editor editing GameObjects, another for ingame editing Entities)
    2. Build one editor which edits entities (ignore GameObjects and baking)
    I opted for the second option which brings some difficulties with it as it requires running the ECS world in edit mode.
    The paradigm of edit and runtime data just doesn't fit well here.
     
    lclemens, defic, Opeth001 and 2 others like this.
  12. tartiflette25

    tartiflette25

    Joined:
    Nov 6, 2016
    Posts:
    55
    Is there any Entity 1.0 samples or demos? Even work in progress.
    Running into a bunch of issues trying to upgrade the ECSSamples for entity 0.51.
     
    JohngUK likes this.
  13. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,775
    There is a post somwhere with link to Unity training github repository, for Entities 1.0. Try to find one here on Unity DOTS forum. It maybe of help for you. Srr I am on the mobile atm.
     
    Opeth001 and tartiflette25 like this.
  14. Onigiri

    Onigiri

    Joined:
    Aug 10, 2014
    Posts:
    484
    There is 1.0 branch in ECSSamples repo
     
    JohngUK and tartiflette25 like this.
  15. tartiflette25

    tartiflette25

    Joined:
    Nov 6, 2016
    Posts:
    55
    Oh dear, thank you!
     
  16. Valkrysa_Herja

    Valkrysa_Herja

    Joined:
    Aug 1, 2014
    Posts:
    41
    Is the new transform component intended to be deterministic across machines?
    This says transform will be 8 floats so I'm thinking we'll still have indeterminism across multiplayer simulations but just wanted to ask since determinism would be such a great checkmark.
     
    Ryetoast likes this.
  17. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    Does it mean I can finally make a editor only assembly definition without getting compile error anymore when try to build player runtime and also sometimes has weird compile error at authoring MonoBehavior?


    I think I already stressed how incredible important this build config feature quite number of times that build config enables the possibility to get different player runtime build easily. Without build config I can't imagine how could I achieve the same thing. Instead of spending a lot of time consolidating build systems I think making this platform package to be first class citizen for both dots and OOP projects is much better decision. From what I see platform package is technically implemented on top current build systems. I think just continue to maintain this platform package and slowly improve it is the better road to go. You can make it even better in future by using Scriptable Build Pipeline as what u mention to make it become something like URP and HDRP that is built on top Scriptable Render Pipeline as long term plan. What I want to bring out is instead of just directly deprecate platform package you can slowly improve platform package and make it compatible for both dots and oop projects
     
    Last edited: Sep 28, 2022
    MostHated likes this.
  18. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    Can you continue to explore the way to write parallel jobified code off the main thread that still using idiomatic foreach approach that can be as easy as Entities.ForEach? IJobEntity just too many boilerplate typing for most of the use case that is just too time consuming that in future I want main thread code to become jobified code I need to spend quite some time to make it work which is really tedious and boring. And also I think it's really critical for the last minute optimization when ur game is going to ship very soon in few days.


    Want to confirm that can I just use idiomatic foreach approach at SystemBase or this idiomatic foreach approach is at ISystem only?

    Do u mean that in future release, Aspects can be evolved to codegen truly efficient code that system only read/write the only required data? For example, when using TransformAspect u only read Translation component then will codegen only read Translation component.

    Any plan to make ISystem much more less typing? At least remove the need to add lots of BurstCompile attribute to struct ISystem and all the ISystem methods.
     
    Last edited: Sep 28, 2022
    Ryetoast likes this.
  19. peaj_metric

    peaj_metric

    Joined:
    Sep 15, 2014
    Posts:
    146
    Thats also the reason I use the platforms package for all of my projects regardless of DOTS or not.
    Having different build settings per "platform" is just not sufficient enough.
    I often require different build settings/configs for different storefronts or VR devices or even building a level editor and a game/main application (different scenes) from the same project.
    It was also nice to integrate additional build steps. Such as injecting a version number.

    I would have maintained/extended my custom build manager if I hadn't relied on Unities platforms package for so long.
    No I will have to start from scratch I guess.

    But the decision here seems to be pretty final
     
    iamarugin likes this.
  20. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,775
  21. PolarTron

    PolarTron

    Joined:
    Jun 21, 2013
    Posts:
    94
    1.0 made me realize that my DOTS code can be written to be completely stateless. As in I can keep all my data inside singleton and system components.

    A really good starting point to have a visual scripting system (I bet you're doing something internally).
     
    apkdev likes this.
  22. officialfonee

    officialfonee

    Joined:
    May 22, 2018
    Posts:
    44
    Right, sorry for my ignorance!
     
  23. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    Why is [BurstComplie] opt-in on the ISystem? :)
     
    Ryetoast and lclemens like this.
  24. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Is the 2021 editor version still the recommended/required version for the 1.0 package?
     
  25. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,684
    MostHated likes this.
  26. BuzzJive

    BuzzJive

    Joined:
    Mar 6, 2014
    Posts:
    75
    There are crashes when running the 1.0 experimental samples on 2022.2.0b9 (did not try b8). Specifically, running the HybridURPSamples - the scenes load and run as expected until you get to the Lightmaps scene where the editor crashes - and backwards when you get to Submesh. Running on Windows 10 in Windows Editor mode. Filed a bug with the crash:

    IN-18202 - ECS 1.0 experimental samples crash on 2022.2.0b9
     
  27. BogdanM

    BogdanM

    Joined:
    Sep 3, 2017
    Posts:
    8
    One of the changes that is not mentioned in this post but present in the Change Log of the Entities Package, is this
    I cannot stress enough how worrying this is to me. A hard cap at 128?! I feel like it goes completely against the "Optimizable by default" mantra of DOTS. I am aware that the engineers behind the Package are considering a multitude of aspects, but as a user, this feels like it's absolutely not worth it for a feature that can be achieved with a simple bool inside the component and an early exit during the processing of the data (as it was mentioned in the post above).

    One of the metrics mentioned was "9x faster than structural changes", which is fair enough, but structural changes are one thing, and we know to avoid it through better architecting, up to the point where it's unavoidable and ECBs come into play. I am curious though how much faster the IEnableable approach is in comparison to a custom bool and if approach.

    I would love to hear some other motivations behind this, or some stress test results. The one thing I am most curious about is: "Are higher Chunk Capacities not linearly related to performance?" My core responsibility when architecting in DOTS is to reduce the memory footprint of Archetypes up to 250-650 Chunk Capacity, and this change kinda puts me out of work ^^'. My intuition tells me that 4x Chunk Capacity leads to 4 times fewer cache misses, and I personally would not trade that for "faster 'enabled' query filter".
     
    Last edited: Sep 29, 2022
    rdjadu, lclemens, Arnold_2013 and 4 others like this.
  28. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,266
    Profile it. There's massively diminishing returns after a certain entity count. 128 is more than plenty. If you have tiny archetypes, using entities might be the wrong tool for the job. There's more optimizations to limiting chunk sizes to 128 than just enabled components. If you ever do stuff with chunk components, you will appreciate this change.
     
    officialfonee, RaL and Luxxuor like this.
  29. tgkthefirst

    tgkthefirst

    Joined:
    Dec 27, 2020
    Posts:
    13
    One question regarding IConvertGameObjectToEntity
    is that deprecated as well? I see no mention of its deprecation in the docs
    EDIT: My bad, it seems it only works with the old conversion system
     
    Last edited: Sep 29, 2022
  30. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    I am definitely for this as well. Keeping the much more easily customizable and powerful build system that many of us rely on and are already using, and building the base functionality into that instead is a much better idea to me
     
  31. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    Can I access to managed component (aka class component) from ISystem struct withtout BurstCompile attribute? or should I use SystemBase for that?
     
    DatCong likes this.
  32. DatCong

    DatCong

    Joined:
    Nov 5, 2020
    Posts:
    87
    No, BurstCompile and No ManagedData.
     
    Kichang-Kim likes this.
  33. aducceschi

    aducceschi

    Joined:
    Feb 9, 2022
    Posts:
    39
    How can I now change the Entities Physics Timestep?
    And how can I now Schedule Trigger Jobs? It throws me an error when I try to do it:
    The type "name.TriggerJob" cannot be used as type parameter "T" in the generic type or method "IJobEntityExtensions.Schedule<T>(T,JobHandle)". There is no boxing conversion from "name.TriggerJob" to "Unity.Entities.IJobEntity".

    Also EndFramePhysicsSystem and StepPhysicsWorld no longer exist.
     
  34. Karearea

    Karearea

    Joined:
    Sep 3, 2012
    Posts:
    386
    I was able to modify my triggers to match the example here -seems to work ok
     
    aducceschi likes this.
  35. aducceschi

    aducceschi

    Joined:
    Feb 9, 2022
    Posts:
    39
    Thank you very much I'll check it out!
     
    Karearea likes this.
  36. aducceschi

    aducceschi

    Joined:
    Feb 9, 2022
    Posts:
    39
    Figured it out.

    In order to get/set Timestep use GetExistingSystemManaged, instead of GetExisitingSystem.
     
  37. IsaacsUnity

    IsaacsUnity

    Unity Technologies

    Joined:
    Mar 1, 2022
    Posts:
    94
    Thank you for flagging this. We're aware of this issue and are currently working on a fix that should be available in a couple of weeks.
     
    optimise likes this.
  38. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    This crash needs new editor version or new dots package to fix it?
     
  39. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    One strategy might be to convert prefabs or groups of entities at bake time and instantiate them individually (and optionally compose them according to whatever your runtime criteria is). We'll be posting more baking related content soon, keep a lookout for a more comprehensive guide linked in the forums.

    Right.

    I can't speak to the release schedule of anything unannounced just yet, but if you provide more info on your use case someone might be able to weigh in.
    Also, check out the 1.0 related content in the sample repo:
     
  40. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    We're aware of the issue, have reproduced it locally, and anticipate a fix in an imminent editor release.
     
  41. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    How about cannot build player runtime error when pressing build at android build config? Can u provide the code snippet at here so I can fix locally? I believe it's caused by some code logic bug at package. Or it's just sample missing some setup reference?

    ArgumentException: Invalid GUID 00000000000000000000000000000000
    Unity.Scenes.Editor.GameObjectSceneMetaDataImporter.GetGameObjectSceneMetaData (Unity.Entities.Hash128 sceneGUID, System.Boolean async, Unity.Entities.BlobAssetReference`1[Unity.Scenes.Editor.GameObjectSceneMetaDataImporter+GameObjectSceneMetaData]& sceneMetaDataRef) (at Library/PackageCache/com.unity.entities@1.0.0-exp.8/Unity.Scenes.Editor/GameObjectSceneMetaDataImporter.cs:73)
    Unity.Scenes.Editor.GameObjectSceneMetaDataImporter.GetSubScenes (UnityEditor.GUID guid) (at Library/PackageCache/com.unity.entities@1.0.0-exp.8/Unity.Scenes.Editor/GameObjectSceneMetaDataImporter.cs:79)
    Unity.Scenes.Editor.EditorEntityScenes.GetSubScenes (UnityEditor.GUID guid) (at Library/PackageCache/com.unity.entities@1.0.0-exp.8/Unity.Scenes.Editor/EditorEntityScenes.cs:1168)
    Unity.Scenes.Editor.SubSceneFilesProvider+<>c.<OnBeforeRegisterAdditionalFilesToDeploy>b__3_0 (System.String scenePath) (at Library/PackageCache/com.unity.entities@1.0.0-exp.8/Unity.Scenes.Editor/SubSceneFilesProvider.cs:33)
    System.Linq.Enumerable+SelectManySingleSelectorIterator`2[TSource,TResult].MoveNext () (at <b017b385d9884952b62c7b35f9fed747>:0)
    System.Collections.Generic.HashSet`1[T].UnionWith (System.Collections.Generic.IEnumerable`1[T] other) (at <b017b385d9884952b62c7b35f9fed747>:0)
    System.Collections.Generic.HashSet`1[T]..ctor (System.Collections.Generic.IEnumerable`1[T] collection, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <b017b385d9884952b62c7b35f9fed747>:0)
    System.Collections.Generic.HashSet`1[T]..ctor (System.Collections.Generic.IEnumerable`1[T] collection) (at <b017b385d9884952b62c7b35f9fed747>:0)
    Unity.Scenes.Editor.SubSceneFilesProvider.OnBeforeRegisterAdditionalFilesToDeploy () (at Library/PackageCache/com.unity.entities@1.0.0-exp.8/Unity.Scenes.Editor/SubSceneFilesProvider.cs:33)
    Unity.Build.Classic.Private.CopyAdditionallyProvidedFilesStepBeforeBuild.Run (Unity.Build.BuildContext context) (at Library/PackageCache/com.unity.platforms@1.0.0-exp.6/Editor/Unity.Build.Classic.Private/NonIncremental/Steps/CopyAdditionallyProvidedFilesStepBeforeBuild.cs:26)
    Unity.Build.BuildStepCollection.Run (Unity.Build.BuildContext context) (at Library/PackageCache/com.unity.platforms@1.0.0-exp.6/Editor/Unity.Build/BuildStepCollection.cs:77)
    UnityEngine.Debug:LogException(Exception, Object)
    Unity.Build.BuildPipelineResult:LogResult() (at Library/PackageCache/com.unity.platforms@1.0.0-exp.6/Editor/Unity.Build/BuildPipelineResult.cs:46)
    Unity.Build.Editor.BuildAction:Execute(BuildConfiguration) (at Library/PackageCache/com.unity.platforms@1.0.0-exp.6/Editor/Unity.Build.Editor/BuildConfigurationInspector.cs:54)
    Unity.Build.Editor.<>c__DisplayClass45_1:<Build>b__12() (at Library/PackageCache/com.unity.platforms@1.0.0-exp.6/Editor/Unity.Build.Editor/BuildConfigurationInspector.cs:238)
    UnityEditor.EditorApplication:Internal_CallDelayFunctions()
     
  42. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Edit - I saw this post before the above response that it was known.

    I had a similar experience on Linux attempting to run the most basic sample in the folder, whichever #1 was, something like "add a component". Simply hitting play crashed and closed the editor.
     
  43. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    That the same issue as here? We're investigating.
     
    optimise likes this.
  44. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    966
    Just one single question: Why is enabled/disabled components and the 128 entities cap not OPTIONAL?
     
    Tony_Max likes this.
  45. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    Kill Entities.ForEach with fire and extreme prejudice, please.
    Do not keep it around. You haven't kept inject around, either.
     
    horeaper likes this.
  46. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,775
    New shorthand approach is even uglier than entities foreach lambda to be honest, in terms of readibility.
     
    Niter88, Ryetoast, Singtaa and 11 others like this.
  47. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Am I the only person liking Entities.ForEach here?
    New Query API looks more like Linq, and I hate that thing. (burn it with fire :D)

    Probably now is the right time to get the hang of IJobEntity style.

    Anyway, lots of good info here. Thanks.
     
  48. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    We like it fine too, it just kills iteration time, and we couldn't make it stop.

    [Edit: for me EFE looks more like linq than the new foreach thing. Also, linq is really slow, whereas this is very fast :) ]
     
    Daxode and Elapotp like this.
  49. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    76
    Since enabled components are optional I read this question as "why isn't the 128 entities chunk limit special cased only to archetypes which contain enablable components?"

    We take advantage of the 128 entity limit to employ some optimizations, particularly the use of SIMD, that make both the general case and the enableable case faster. Obviously performance depends a lot on context and YMMV, but it was pretty rare for us to find an archetype that we thought represented a likely user situation that performed differently enough to justify the problems that maintaining a separate code path would introduce.

    That said, part of having an experimental release is getting early feedback from folks who may run into problems and situations we didn't anticipate (or with a differing frequency). If the 128 entity limit presents a performance problem for you we'd love to hear more about it.
     
  50. BogdanM

    BogdanM

    Joined:
    Sep 3, 2017
    Posts:
    8
    Ok, I eventually got around to profiling, and I got some mixed results between 2 test cases. (using Entities 0.51.1)

    1. One floating point operation per Job across 1 Million Entities saw a pretty strong correlation between Chunk Capacity and execution time - getting on average 2.9 faster processing for each 2.5 increase in Chunk Capacity

    2. 100 floating point operations per Job across 100K Entities showed pretty much no correlation between Chunk Capacity and execution time

    Archetypes used
    Archetypes.png

    Execution times for 1 floating point operation - 1M Entities
    Profiler.png

    ProfileData.png

    Execution times for 100 floating point operations - 100K Entities
    Profiler2.png

    I guess the conclusion is that it depends on your use case... weather is more computationally intensive Jobs with fewer Entities or smaller Jobs across more Entities. Either way, I would keep my stance on the 128 hard cap, that it should at least be optional ^^
     
    Last edited: Oct 3, 2022
    Niter88 likes this.