Sorting layers in scroll galleries: in-depth tutorial

This tutorial is part of a series on how to construct an awesome-looking scroll gallery, with inertia, snapping, zoom and other stuff. Today we’ll deal with sorting layers in unity 3d.

How does sorting layers in unity work?

Last time we had seen how to set up a scroll gallery, with a nice zoom effect, but in the end the order of images is a fixed thing. Worse than ever, Unity3d in both Screen spaces Overlay and Camera doesn’t look at z-axis to decide what to draw on what, but at the order in hyerarchy; so if we want what’s bigger to also stay on top, we’ll need some trickery.

Let’s see the code!

Specifically well’ need to change our refreshImage function from last tutorial and to use another AnimationCurve:

    public AnimationCurve orderFactor;

With this value:

zig up, zag down - order function for sorting layers in unity
Just keep growing 0-0.5 and set “ping-pong” in the little gear-menu so that you get a constant decrease in 0.5-1 – order function for sorting layers in unity

Now, remember the refreshImage function? It was like this:

    protected virtual void refreshImages()
    {
        foreach (var img in imgset)
        {
            float transformedPosition = positionCurve.Evaluate(alpha + alphaoff[img]);
            img.localPosition = Vector3.right * (transformedPosition * swipeFieldWidth - (swipeFieldWidth / 2f));
            img.localScale = Vector3.one * (zoomCurve.Evaluate(transformedPosition));
        }
    }

So we’ll change it “a bit”.

 protected virtual void refreshImages()
    {
        List<KeyValuePair<RectTransform, float>> orderingLayerList = new List<KeyValuePair<RectTransform, float>>();
        foreach (var img in imgset)

We’ll use this list as a dictionary to hold information about the order value for each image. We won’t use a Dictionary since it cannot be trusted with keeping order.

At the end of the foreach cycle we then add:

            img.localScale = Vector3.one * (zoomCurve.Evaluate(transformedPosition));
            orderingLayerList.Add(new KeyValuePair<RectTransform, float>(img, orderFactor.Evaluate(alpha + alphaoff[img])));
        }

We just use the alpha+alphaoff of the image to get a point on the order function. Then record it in our list. After that, we just get our shit sorted out:

        var orderByVal = orderingLayerList.OrderBy(kvp => kvp.Value);

Wish it was that easy in real life…

From values to actual layer sorting

Now we can at last sort our hyerarchy in the order we have obtained, with a fast insertion sort approach. We just put as “last” every item starting from the lowest order value so that our highest values come out on top:

        foreach (var item in orderByVal)
        {
            item.Key.SetAsLastSibling();
        }

And that’s all.  We now have our gallery sorted out like we wanted, with the biggest images on the center and on top of the other images. Of course there still must be a lot of effects and we’ll need a selection mechanism, but that’s coming with next parts of this tutorial. Don’t lose them,  join my newsletter and I’ll keep you posted. [edit: next part is here]

Copy-paste from here:

    public AnimationCurve orderFactor;

    protected virtual void refreshImages()
    {
        List<KeyValuePair<RectTransform, float>> orderingLayerList = new List<KeyValuePair<RectTransform, float>>();
        foreach (var img in imgset)
        {
            float transformedPosition = positionCurve.Evaluate(alpha + alphaoff[img]);

            img.localPosition = Vector3.right * (transformedPosition * swipeFieldWidth - (swipeFieldWidth / 2f));

            img.localScale = Vector3.one * (zoomCurve.Evaluate(transformedPosition));
            orderingLayerList.Add(new KeyValuePair<RectTransform, float>(img, orderFactor.Evaluate(alpha + alphaoff[img])));
        }
        var orderByVal = orderingLayerList.OrderBy(kvp => kvp.Value);
        foreach (var item in orderByVal)
        {
            item.Key.SetAsLastSibling();
        }
    }
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •