Sorting 2D sprites

As sprites move around the screen in an isometric 2D adventure game, they need to show up in front of and behind other sprites as they move.  Most of the Unity 2d tutorials only address basic sorting and mainly in side-scroller type games.

The way I solve this in Bik is to attach a Baseline.cs script to any sprite that needs to move. If the sprite moves in the XY plane, the script will calculate the Z index depth that the sprite should be at.

Make sure the sprite is aligned bottom so it’s feet are at the transform coordinates of the sprite GameObject.

Here is a simplified version of the script I use in Bik.

//store the new Z position
float newZPos;
//the camera looking at the sprite
Camera cam;
//the local transform for speed
Transform trans;

void Start()
{
    cam = Camera.main;
    trans = transform;
}

void Update()
{
    //don't run if sprite is not visible to any camera
    if(!renderer.isVisible)
        return;

    //store the viewport position of this GameObject.  
    Vector3 viewportPos = cam.WorldToViewportPoint(trans.position);

    //now we convert our position in the viewport to a usable number for the z order.	 
    //This will always give us a number between 0 and 5. based on the Y value from the viewportPos.
    //0 will be the top of the screen and 5 would be the bottom. In the isometric view, objects higher on the screen would be "behind" objects lower on the screen.
    newZPos = ConvertScale(viewportPos.y, 0,1,5,0); //See my convert scale method below
		
    //change the Z position of the GameObject to the newly calculated position between 0 - 5.  
    trans.position = new Vector3(trans.position.x,trans.position.y,newZPos);
   
}

//this is a static float I use to convert scales.  This is normally placed in a helper script, but i'll show you it here.
public static float ConvertScale (float old_value, float old_min, float old_max, float new_min, float new_max)
{
	float new_value = ((old_value - old_min) / (old_max - old_min)) * (new_max - new_min) + new_min;
	return new_value;
}

 
Instead of running this in the Update it would be smart to have this script subscribe to a C# event on your Movement script for this character/object. So when the character moves this would be run in a coroutine and then stopped when the character stops moving.
Check out my previous posts for more about Events.

Or just have this as a method directly in your movement script!

Hope this helps someone out! Let me know any questions or comments!

 

This entry was posted in DevBlog. Bookmark the permalink.

5 Responses to Sorting 2D sprites

Leave a Reply

Your email address will not be published. Required fields are marked *