How is the Array.Sort actually working to give the desired result

So I have everything working fine and found the challenge easy, but I’m not 100% sure how it’s actually working.

So I understand that we rearranged the hits array based on the distance of each raycast.

but in the code where its actually sets the raycastable:

    foreach (RaycastHit hit in hits)
            {
                IRaycastable[] raycastables = hit.transform.GetComponents<IRaycastable>();
                foreach (IRaycastable raycastable in raycastables)
                {
                    if (raycastable.HandleRaycast(this))
                    {
                        SetCursor(raycastable.GetCursorType());
                        return true;
                    }
                }
            }

Does this work because the foreach for the hits will keep overwriting the previous Iraycastable in the nested Iraycastable array because the Iraycastable that is the closest is a later element in the hits array? that was quite a mouthful hopefully that made sense

I think this question confused me…

If you’re wondering about sorting the IRaycastables on the GameObject, they’re generally going to be in the order they are found on the GameObject.

My apologies it was quite difficult for me to explain and I don’t think I worded it well.

I basically was trying to break down and ask through each step of the code what actually leads to the Iraycastable that is clicked closest to the camera to be the one chosen.

From my understanding, the sort function just adds a key for the distance float values but doesn’t actually sort. So I was basically asking if it’s the foreach I pasted above that’s selecting the closest.

I’ll add the original code because I’m looking at fresh from the lecture taking for granted you haven’t just seen it yourself:

 RaycastHit[] RaycastAllSorted()
        {
            RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
            float[] distances = new float[hits.Length];

            for (int i = 0; i < hits.Length; i++)
            {
                distances[i] = hits[i].distance;
            }

            Array.Sort(distances, hits);
            return hits;
        }

Hopefully that makes sense now, If my question is still unclear don’t worry we’ll leave it I was curious but its not that essential for me to know.

This particular flavor of Array.Sort is a magic function. It’s relatively easy to sort an array of floats. When you sort an array of floats, you know what you need to compare, float to float. Sorting an array of Hits, hwoever, is not so simple… You have to know what key to sort on in the first place, and lots of the stuff in Hit() doesn’t even make sense to sort…

So what we’re doing is creating an array with the exact same number of elements as Hit() with the hit.distance in the values. Then we tell Array.Sort to sort the distances array, and while we’re at it, wherever you moved an element in distances, also move that element in hits.

I’ll post a quick example, but not from this computer.

1 Like

Here’s an example of how Array.Sort() works (but the real Array.Sort() is native code and runs much quicker)

public static class ArraySortingExample
{
    public static void SortExample<T, U>(T[] firstArray, U[] secondArray) where T : IComparable<T>
    {
        int length = Mathf.Min(firstArray.Length, secondArray.Length);
        if (length <= 1) return; //nothing to sort
        bool sorted = true;
        do
        {
            sorted = true; //Assume we're sorted until we have evidence to the contrary
            for (int i = 0; i < length - 1; i++)
            {
                if (firstArray[i].CompareTo(firstArray[i+1])>0)
                {
                    (firstArray[i], firstArray[i + 1]) = (firstArray[i + 1], firstArray[i]); 
                    (secondArray[i], secondArray[i + 1]) = (secondArray[i + 1], secondArray[i]);
                    sorted = false;
                }
            }
        } while (!sorted);
    }
}
3 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms