0
\$\begingroup\$

I have a list of GameObject , and I need to know which one is the last in the hierarchy ( This is for a UI system, So is kind of 'which one is showing up')

I have a cursor managed by GamePad , and I use Raycast to see if he clicked something, It give me an array of Gameobjects but I need to know which one is showing up(on top of the others) to click on it

Example this is my full hierarchy:

GameObject A
        GameObject B
        GameObject C
GameObject D
        GameObject E
        GameObject F
GameObject G
          GameObject H
               GameObject I
           GameObject J 

The list of raycast contain 'GameObject D','GameObject A','GameObject I'

How I cand find that 'GameObject I' is the last one? they don't have a common root

\$\endgroup\$
2
  • \$\begingroup\$ Are you using Raycast or RaycastAll? Because afaik, Raycast method will only give info on the first thing it hits but RaycastAll is going to go through all of the objects. see: docs.unity3d.com/ScriptReference/Physics.Raycast.html (second definition with the hitinfo) and docs.unity3d.com/ScriptReference/RaycastHit.html \$\endgroup\$ Commented Sep 25, 2017 at 12:27
  • \$\begingroup\$ I am using Raycast, but it is Graphic Raycast, that differ from normal raycast, thanks for the comment anyway! \$\endgroup\$ Commented Sep 26, 2017 at 7:52

1 Answer 1

2
\$\begingroup\$

Here is a script I've made to determine which Transform is the "front most" according to the hierarchy. But be careful, if one of the "candidates" has a higher z value, the function will return the wrong result :

// Call this function by giving an array of transforms
public Transform GetFrontMost( Transform[] transforms )
{
    List<List<int>> siblingIndices = new List<List<int>>();

    for ( int i = 0 ; i < transforms.Length ; i++ )
    {
        siblingIndices.Add( GetSiblingIndices( transforms[i] ) );
    }

    Transform frontMost = null;
    int depth = 0;
    bool conflict = true;
    int maxSibling = -1;

    while ( conflict )
    {
        conflict = false;
        maxSibling = -1;

        for ( int transformIndex = 0 ; transformIndex < siblingIndices.Count ; transformIndex++ )
        {
            if ( depth < siblingIndices[transformIndex].Count )
            {
                if ( siblingIndices[transformIndex][depth] > maxSibling )
                {
                    conflict = false;
                    maxSibling = siblingIndices[transformIndex][depth];
                    frontMost = transforms[transformIndex];
                }
                else if ( siblingIndices[transformIndex][depth] == maxSibling )
                {
                    conflict = true;
                    frontMost = null;
                }
            }
        }

        depth++;
    }

    return frontMost;
}

private List<int> GetSiblingIndices( Transform t )
{
    if ( t.parent == null )
        return new List<int>() { t.GetSiblingIndex() };
    else
    {
        List<int> list = GetSiblingIndices( t.parent );
        list.Add( t.GetSiblingIndex() );
        return list;
    }
}

Supposing you have a hierarchy as below, if you give 'GameObject D','GameObject A','GameObject I', the function should return 'GameObject I'.

GameObject A
        GameObject B
        GameObject C
GameObject D
        GameObject E
        GameObject F
GameObject G
          GameObject H
               GameObject I
           GameObject J 

In the code above :

  1. For each "candidates", you get an array containing the sibling indices of all its parent
  2. You compare the indices, candidate by candidate. If you find one candidate with a higher sibling index for a given depth, you have found the frontmost element
  3. Else, you go deeper in the hierarchy to make the comparisons
\$\endgroup\$
2
  • \$\begingroup\$ Very usefull script thanks! However I found that GraphicRaycaster give the results in inverse order of the hierarchy! So I can simply check if the graphic is a clickable ! \$\endgroup\$ Commented Sep 26, 2017 at 7:53
  • \$\begingroup\$ Nice to know! Indeed, it will be simpler in comparison to my script. \$\endgroup\$ Commented Sep 26, 2017 at 8:00

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.