yasirkula / UnityRuntimeInspector

Runtime Inspector and Hierarchy solution for Unity for debugging and runtime editing purposes
MIT License
1.76k stars 139 forks source link

Transforms with only ignored children are expandable #40

Closed i-xt closed 3 years ago

i-xt commented 3 years ago

Description of the bug

Transforms where all children are ignored display the expansion arrow. When clicking the arrow, the children of the transform are hidden correctly though.

expand

The reason for this is that HierarchyData.CanExpand uses the HierarchyData.ChildCount property to determine whether or not an item can be expanded and the HierarchyDataTransform.ChildCount override only checks for the nr of children of a Transform and does not take into account whether they are ignored or not.

https://github.com/yasirkula/UnityRuntimeInspector/blob/cf9a5112b3f6b78325ff0018c15813588dbaf011/Plugins/RuntimeInspector/Scripts/RuntimeHierarchy/HierarchyDataTransform.cs#L19

Reproduction steps

Add a Transform with one child to the hierarchy. Add the child to the ignore list.

Possible Solution

This could be resolved by checking whether or not a Transforms children are ignored. Unfortunately this requires iterating over the Transforms children, but since RuntimeInspectorUtils.IgnoredTransformsHierarchy is a HashSet the performance impact is very low.

    public override int ChildCount
    {
        get
        {
            if( IsSearchEntry || !transform )
                return 0;

            int count = 0;
            foreach( Transform t in transform )
            {
                // Only count children that are not ignored
                if( !RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Contains( t )
                    && ( Root.Hierarchy.GameObjectFilter == null || Root.Hierarchy.GameObjectFilter.Invoke( t ) ) )
                    count++;
            }
            return count;
        }
    }

I can send a PR if this change is welcome, but I was hoping that there might be a more elegant solution to this.

yasirkula commented 3 years ago

If I have 2 child Transforms and the first one is hidden, expand arrow appears but the visible child doesn't show up. To fix this, ChildCount should return either 0 or the actual child count. The following will work:

public override int ChildCount
{
    get
    {
        if( isSearchEntry || !transform )
            return 0;

        for( int i = transform.childCount - 1; i >= 0; i-- )
        {
            Transform child = transform.GetChild( i );
            if( !RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Contains( child ) && ( Root.Hierarchy.GameObjectFilter == null || Root.Hierarchy.GameObjectFilter.Invoke( child ) ) )
                return transform.childCount;
        }

        return 0;
    }
}

I'm really not sure if the extra CPU cycles is worth the effort, though. ChildCount is called once per visible Transform at each RuntimeHierarchy refresh. If you put a Debug.Log inside it, you'll see that it's called a lot.

Even Unity's own Project window has this issue: if you hide packages via top-right button, the arrow next to Packages folder will still be visible (it mush be collapsed first) even if there are no visible packages inside it. It hasn't been distracting to me so far.

i-xt commented 3 years ago

Thanks for your input. I guess it depends quite a lot on the use case of the plugin. If there are lot of Transforms with only ignored children it might be worth the extra CPU cost. If that's rarely the case, probably not.

yasirkula commented 3 years ago

I agree. IMHO, it is generally the latter case. In the former case, users can use this thread as reference to modify their scripts.