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. Dismiss Notice

PSA: Workaround for OrderFirst/OrderLast not working in [UpdateInGroup] attribute

Discussion in 'Entity Component System' started by cort_of_unity, Oct 15, 2020.

  1. cort_of_unity

    cort_of_unity

    Unity Technologies

    Joined:
    Aug 15, 2018
    Posts:
    97
    Hello! Earlier this year, the Entities 0.11 package added a new feature to the UpdateInGroup attribute, which let a system request OrderFirst=true or OrderLast=true in addition to specifying in which system group it should update. We've recently had some reports from users that this feature is not working as expected. This thread describes the problem and a simple fix. If you just want the fix, skip to the bottom for the TL,DR version; otherwise, strap in for some broader context!

    What's the feature?
    It's not uncommon to have a system that needs to update before or after every other system in its ComponentSystemGroup. Establishing this ordering constraint using individual [UpdateBefore] or [UpdateAfter] attributes on every pair of systems in the group can be tedious, if not outright impossible. This is the problem the new optional OrderFirst and OrderLast arguments to [UpdateInGroup] are meant to solve. They effectively add two new "buckets" a system can be placed into during the system sorting process. A system tagged with [UpdateInGroup(typeof(MyGroup), OrderFirst=true)] will be sorted into MyGroup's "early" bucket, while a system tagged with [UpdateInGroup(typeof(MyGroup), OrderLast=true)] goes into MyGroup's "late" bucket. A system that doesn't request OrderFirst=true or OrderLast=true goes into the default ("middle") bucket, and of course specifying both OrderFirst=true and OrderLast=true in the same group is an error.

    Systems within each bucket can use [UpdateBefore] and [UpdateAfter] to order themselves relative to each other as usual, even within the early and late buckets (e.g. two systems with OrderFirst=true can still use [UpdateBefore] to establish the order of those system updates within the early bucket). However, [UpdateBefore] and [UpdateAfter] constraints targeting systems in different buckets (or different system groups) are invalid; they are at best redundant (e.g. a system in the middle bucket asking to [UpdateAfter] a system in the early bucket will emit a warning, but is otherwise harmless) and at worst contradictory (e.g. a system in the middle bucket asking to [UpdateBefore] a system in the early bucket will emit an error). In the final sorted order, all systems in the middle bucket will appear after all systems in the early bucket, and before all systems in the late bucket.

    What's the problem?
    Implementing support for this feature (as well as a few unrelated features) required adding a completely new code path for system sorting. The old sorting path was marked as deprecated, but we kept it as the default behavior (with a warning) for all ComponentSystemGroups to avoid breaking existing projects. Individual system groups can opt into the new sorting path by setting their UseLegacySortOrder property to false; adding this one line in the constructor enables the new system sorting path for that group, and allows its systems to use OrderFirst and OrderLast. The built-in Entities system groups all set UseLegacySortOrder to false, and use OrderFirst and OrderLast extensively to control the sort order of their systems.

    The problem (obvious in hindsight) was that a) we did not effectively communicate this requirement, and b) we did not add a warning to the old sorting path if it encountered these new OrderFirst and OrderLast arguments; it just quietly ignores them, which generally leads to unexpected and incorrect sorting results. This was our mistake, and I apologize profusely for any time DOTS developers have wasted as a result of this oversight. Fortunately, the workaround is trivial:

    What's the solution?
    • In Entities 0.14 and earlier, any system group that wants to use OrderFirst and OrderLast should set ComponentSystemGroup.UseLegacySortOrder to false. Adding that one line to the system group's constructor has fixed every issue with OrderFirst and OrderLast that we've encountered so far.
    • Entities 0.15 was skipped; nothing to see here.
    • In Entities 0.16 and later, the deprecated old system sorting path (and the associated UseLegacySortOrder property) have been removed, and the new sorting path is the default (only) behavior for all system groups, so no special action is needed to use the OrderFirst/OrderLast feature.
    If this fix doesn't resolve your issues with OrderFirst & OrderLast, please let us know!
     
    Last edited: Oct 22, 2020
    lclemens, Vaarz, jdtec and 3 others like this.
  2. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,032
    Hi @cort_of_unity. Any ETA that Entities 0.15 and 0.16 will release?
     
  3. s_schoener

    s_schoener

    Unity Technologies

    Joined:
    Nov 4, 2019
    Posts:
    81
    0.16 is scheduled to release in late October, 0.15 was skipped. No promises that all of this is actually happening, but that's our best guess right now.
     
  4. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    The new sorting is more about Unmanaged System.
    How would Unmanaged-System's progress be in 0.16?
     
  5. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    863
    Thanks, this is very valuable information!