logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class HudElementTreeOrderGui

    The Unity-side adapter over HudElementTreeOrder: projects a HUD's serialized element list into the pure solver's input, and carries out the sibling-aware move, remove and duplicate operations the nested list's row actions need.

    Inheritance
    object
    HudElementTreeOrderGui
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.GameUi.Infrastructure.Editor.Builder
    Assembly: Serenity.UnityGameUi.Infrastructure.Editor.dll
    Syntax
    public static class HudElementTreeOrderGui
    Remarks

    Every method here reads and writes UnityEditor.SerializedProperty only, never the deserialized UnityHudDefinition target object. CreateHudWindow applies its scratch instance's modified properties once, at the end of OnGUI — reading the target object mid-frame would see last frame's data and index straight past the end of an array a row action just grew or shrank this frame.

    Methods

    DescendantsOf(IReadOnlyList<Row>, int)

    Every descendant of the element at elementIndex, in tree display order — usable past HudDefinitionScanner.MaxChainWalkDepth, since ParentElementIndex never clamps.

    Declaration
    public static List<int> DescendantsOf(IReadOnlyList<HudElementTreeOrder.Row> rows, int elementIndex)
    Parameters
    Type Name Description
    IReadOnlyList<HudElementTreeOrder.Row> rows

    Rows from SolveFrom(SerializedProperty).

    int elementIndex

    The element whose descendants to collect.

    Returns
    Type Description
    List<int>

    Every descendant's array index, in display order.

    Remarks

    Walks the actual parent edges rather than comparing Depth, which is clamped for readable indentation, so a box nested past the cap and its own children can end up reporting the SAME depth number — a depth-only comparison would then read the children as siblings instead, silently orphaning them from remove/duplicate/filter. SolveFrom(SerializedProperty) still guarantees depth-first order (a node's whole subtree is a contiguous run right after it), so this only needs to track which element indices are "inside" as it scans forward, not compare numbers.

    DuplicateSubtree(SerializedProperty, int, Func<string, string>)

    Duplicates an element. A childless one is copied on its own, exactly as before; one holding children duplicates the whole subtree, so a copied box arrives with its own copied contents rather than an empty shell.

    Declaration
    public static int DuplicateSubtree(SerializedProperty elements, int index, Func<string, string> makeUniqueId)
    Parameters
    Type Name Description
    SerializedProperty elements

    The serialized element list.

    int index

    Position of the element to duplicate.

    Func<string, string> makeUniqueId

    Given a candidate id, returns one not already used in elements.

    Returns
    Type Description
    int

    The array index the duplicated root element ends up at.

    Remarks

    A duplicated subtree's copies intentionally still reference whatever layer assets, feedback definitions and other shared assets the originals did — the same divergence warning an ordinary single-element duplicate already risks applies here too, once for every copied member.

    Acknowledged tradeoff: Serenity.GameUi.Infrastructure.Editor.Builder.HudElementTreeOrderGui.ParkDuplicate(UnityEditor.SerializedProperty,System.Int32)'s insert-then-move-to-end shuffles which trailing rows' isExpanded foldout state (Unity's own, keyed by array position rather than element identity) survives a park operation, since isExpanded is not carried explicitly through the move. In practice this only ever touches already-collapsed rows past the array's tail — nothing a duplicate operation itself expands — so it is not worth the extra bookkeeping to preserve.

    MoveWithinSiblings(SerializedProperty, in Row, bool)

    Swaps a row with its previous or next sibling — never with a row of another parent, which is what makes the move buttons behave sensibly under nesting instead of hopping across box boundaries.

    Declaration
    public static int MoveWithinSiblings(SerializedProperty elements, in HudElementTreeOrder.Row row, bool up)
    Parameters
    Type Name Description
    SerializedProperty elements

    The serialized element list.

    HudElementTreeOrder.Row row

    The row to move; its sibling indices come from SolveFrom(SerializedProperty).

    bool up

    Whether to swap with the previous sibling (true) or the next one (false).

    Returns
    Type Description
    int

    The element's array index after the move — unchanged when there was no such sibling.

    RemoveWithChildrenChoice(SerializedProperty, int)

    Removes an element. A childless one is simply deleted; one holding children asks whether to move them to the root or take the whole subtree with it.

    Declaration
    public static bool RemoveWithChildrenChoice(SerializedProperty elements, int index)
    Parameters
    Type Name Description
    SerializedProperty elements

    The serialized element list.

    int index

    Position of the element to remove.

    Returns
    Type Description
    bool

    Whether anything was actually removed — false when the author cancelled the dialog.

    SolveFrom(SerializedProperty)

    Projects the serialized element list into HudElementTreeOrder.Nodes and solves the display order.

    Declaration
    public static IReadOnlyList<HudElementTreeOrder.Row> SolveFrom(SerializedProperty elements)
    Parameters
    Type Name Description
    SerializedProperty elements

    The serialized list of UnityHudElementDefinition.

    Returns
    Type Description
    IReadOnlyList<HudElementTreeOrder.Row>

    One row per element, in display order; empty when elements is null.

    In this article
    © 2026 Serenity. All Rights Reserved