I was sorely disappointed with the answers. I’m not sure if this will work for everyone, but it works for me.
Here is how you do it. It was actually easier than I thought, but it took time for it to click and for me to get that lightbulb moment.
What you want to do, is have one script which takes all of the Sprites, and adjusts their OrderInLayer based on their Transform (in my example, Transform.position.Z, but in 2D games it would be Transform.position.Y), but keeping the original sorting order of each piece of the character.
So what you do, is simple math:
OrderInLayer = Transform.Position.Y;
Then simply add the original offset OrderInLayer.
It’s as simple as during Start() of the script, grab the original layer using:
OriginalLayer = CharacterPartGameObject.GetComponent().sortingOrder;
Then during update, simply apply the math:
CharacterPartGameObject.GetComponent().sortingOrder = (transform.position.z + HeadLayer) * -1;
Here is a script which takes my character, who is comprised of a Head, Torso, and two parts for his arms/legs.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CharacterOrderInLayer : MonoBehaviour
{
//GameObject LimbPart, is the gameobject with the SpriteRenderer (the gameobject which has the Sprite).
//int LimbLayer, is the original OrderInLayer of the sprite. This is what you want to keep, relative to all other limbs.
//Link all of the gameobjects in the inspector, or you could theoretically use a GetComponentsInChildren method to grab by tag or name or whatever automatically.
//Character's Head Sprite
public GameObject HeadPart;
int HeadLayer;
//Character's Torso Sprite
public GameObject TorsoPart;
int TorsoLayer;
//Character's Right Arm
public GameObject RightForeArmPart;
int RightForeArmLayer;
public GameObject RightBicepPart;
int RightBicepLayer;
//Character's Left Arm
public GameObject LeftForeArmPart;
int LeftForeArmLayer;
public GameObject LeftBicepPart;
int LeftBicepLayer;
//Character's Right Leg
public GameObject RightThighPart;
int RightThighLayer;
public GameObject RightShinPart;
int RightShinLayer;
//Character's Left Leg
public GameObject LeftThighPart;
int LeftThighLayer;
public GameObject LeftShinPart;
int LeftShinLayer;
void Start()
{
HeadLayer = HeadPart.GetComponent<SpriteRenderer>().sortingOrder;
TorsoLayer = TorsoPart.GetComponent<SpriteRenderer>().sortingOrder;
RightForeArmLayer = RightForeArmPart.GetComponent<SpriteRenderer>().sortingOrder;
RightBicepLayer = RightBicepPart.GetComponent<SpriteRenderer>().sortingOrder;
LeftForeArmLayer = LeftForeArmPart.GetComponent<SpriteRenderer>().sortingOrder;
LeftBicepLayer = LeftBicepPart.GetComponent<SpriteRenderer>().sortingOrder;
RightThighLayer = RightThighPart.GetComponent<SpriteRenderer>().sortingOrder;
RightShinLayer = RightShinPart.GetComponent<SpriteRenderer>().sortingOrder;
LeftThighLayer = LeftThighPart.GetComponent<SpriteRenderer>().sortingOrder;
LeftShinLayer = LeftShinPart.GetComponent<SpriteRenderer>().sortingOrder;
}
// Update is called once per frame
void Update ()
{
int Zlayer = Mathf.RoundToInt(transform.position.z); //Turn the gameobject's Z position into an integer, so it can be converted to the layer. (TLDR: Transform.Position.Z = SortingOrder). Change this from Z to Y if you are using Unity2D.
Zlayer -= 90; //Custom Offset, because my sprite is +90z when at position (0x,0y,0z). This is NOT required.
//Each of these takes the individual sprites which make up the character, and then sets the correct SortingOrder based on their Transform.Position, while keeping all of the sprite's relative positioning.
HeadPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - HeadLayer) * -1;
TorsoPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - TorsoLayer) * -1;
RightForeArmPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - RightForeArmLayer) * -1;
RightBicepPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - RightBicepLayer) * -1;
LeftForeArmPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - LeftForeArmLayer) * -1;
LeftBicepPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - LeftBicepLayer) * -1;
RightThighPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - RightThighLayer) * -1;
RightShinPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - RightShinLayer) * -1;
LeftThighPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - LeftThighLayer) * -1;
LeftShinPart.GetComponent<SpriteRenderer>().sortingOrder = (Zlayer - LeftShinLayer) * -1;
}
}