dynamically sorting sprites in a 2d oblique perpective
so I am working on a 2d point and click game where the player moves around in an what is an illusion of 3d space, and for various reasons, I want to keep this project in 2D (the work flow is just better for what I'm doing), however, I'm hitting an issue with getting the player sprite to change its order in the sorting layer as I want it to.
see, I have a project that is emulating this style here, where there player's sprite would need to appear in front of the desk, when in front of it (duh), and in this case, on the left side of it, while it would need to be rendered behind it while on the right, and behind it.
I have scoured the internet looking to see if anyone else has had this issue, or come up with a solution, but I've come up nil.
I have tried working on this myself, and I did get a version of it to work, when the player only needs to work around a single object, but attempting to apply it on a scene with multiple objects the player can walk around breaks it.
here's what I have so far (warning as it is a giant mess):
void Sort()
{
var backOrder = manga.sortingOrder;
var frontOrder = manga.sortingOrder;
var order = 0;
foreach(var item in DynamicLayering)
{
var visual = item.GetComponent<SpriteRenderer>();
var size = new Vector2(visual.sprite.bounds.extents.x * item.transform.localScale.x, visual.sprite.bounds.extents.y * item.transform.localScale.y);
var pos = new Vector2(item.transform.position.x - size.x, item.transform.position.y - size.y);
var rect = new Rect(pos, size * 2);
//if the object's front is infront of the player
if(item.transform.position.y - size.y < transform.parent.position.y)
{
if(item.transform.position.y < transform.parent.position.y)
{
//so the order taken is the farthest back
if (backOrder >= visual.sortingOrder)
{
backOrder = visual.sortingOrder - 1;
}
continue;
}
var playrect = new Rect(new Vector2(transform.position.x - playsize.x, transform.position.y - playsize.y), playsize * 2);
//if the object is in the same plane as the player
if (rect.Overlaps(playrect) && rect.width > 0.5)
{
//if the player is on the visible side
if (item.transform.position.x < transform.parent.position.x && leftsideHidden)
{
//so the order taken is the farthest front
if (frontOrder <= visual.sortingOrder)
{
frontOrder = visual.sortingOrder + 1;
}
continue;
}
if (item.transform.position.x > transform.parent.position.x && !leftsideHidden)
{
//so the order taken is the farthest front
if (frontOrder <= visual.sortingOrder)
{
frontOrder = visual.sortingOrder + 1;
}
continue;
}
}
//so the order taken is the farthest back
if (backOrder >= visual.sortingOrder)
{
backOrder = visual.sortingOrder - 1;
}
}
else
{
//so the order taken is the farthest front
if (frontOrder <= visual.sortingOrder)
{
frontOrder = visual.sortingOrder + 1;
}
}
}
//determining the order position we are in
if (frontOrder == manga.sortingOrder && backOrder != manga.sortingOrder)
{
order = backOrder;
//print("back");
}
else if (frontOrder != manga.sortingOrder && backOrder == manga.sortingOrder)
{
order = frontOrder;
//print("Front");
}
else if (frontOrder == backOrder)
{
order = frontOrder;
//print("same");
}
else
{
//what to do if both sides off?
order = frontOrder;
//print("old");
}
manga.sortingOrder = order;
//print(manga.sortingOrder);
}
I am not at all proud of this code, but this is what I got. its called every frame when the player is moving, loops through the array of objects in its sorting order that are relevant to it (it is filtered to that point elsewhere), to find where its order is to be sorted (objects in the scene have a higher value in the sorting the "closer" they are to the foreground). I feel like my logic is in the right direction, but I'm completely lost on its implementation.