diff --git a/Assets/Scripts/IsoSpriteSorting.cs b/Assets/Scripts/IsoSpriteSorting.cs index aceacfe..f7e568f 100644 --- a/Assets/Scripts/IsoSpriteSorting.cs +++ b/Assets/Scripts/IsoSpriteSorting.cs @@ -4,6 +4,8 @@ using UnityEngine; public class IsoSpriteSorting : MonoBehaviour { + private const float SortingComparisonEpsilon = 0.0001f; + public bool isMovable; [SerializeField] private bool renderBelowAll; @@ -193,6 +195,10 @@ private static int CompareLineAndLine(IsoSpriteSorting line1, IsoSpriteSorting l Vector2 line2Point1 = line2.SortingPoint1; Vector2 line2Point2 = line2.SortingPoint2; + if (TryCompareLineOverlap(line1, line2, out int overlapComparison)) { + return overlapComparison; + } + int comp1 = ComparePointAndLine(line1Point1, line2); int comp2 = ComparePointAndLine(line1Point2, line2); int oneVStwo = int.MinValue; @@ -228,6 +234,49 @@ private static int CompareLineCenters(IsoSpriteSorting line1, IsoSpriteSorting l return -line1.SortingLineCenterHeight.CompareTo(line2.SortingLineCenterHeight); } + private static bool TryCompareLineOverlap(IsoSpriteSorting line1, IsoSpriteSorting line2, out int comparison) { + comparison = 0; + + float line1MinX = Mathf.Min(line1.SortingPoint1.x, line1.SortingPoint2.x); + float line1MaxX = Mathf.Max(line1.SortingPoint1.x, line1.SortingPoint2.x); + float line2MinX = Mathf.Min(line2.SortingPoint1.x, line2.SortingPoint2.x); + float line2MaxX = Mathf.Max(line2.SortingPoint1.x, line2.SortingPoint2.x); + + float overlapMinX = Mathf.Max(line1MinX, line2MinX); + float overlapMaxX = Mathf.Min(line1MaxX, line2MaxX); + if (overlapMaxX - overlapMinX <= SortingComparisonEpsilon) { + return false; + } + + float sampleX = (overlapMinX + overlapMaxX) * 0.5f; + if (!TryGetLineYAtX(line1, sampleX, out float line1Y) || !TryGetLineYAtX(line2, sampleX, out float line2Y)) { + return false; + } + + float yDifference = line1Y - line2Y; + if (Mathf.Abs(yDifference) <= SortingComparisonEpsilon) { + return false; + } + + comparison = yDifference > 0f ? -1 : 1; + return true; + } + + private static bool TryGetLineYAtX(IsoSpriteSorting line, float x, out float y) { + y = 0f; + + Vector2 point1 = line.SortingPoint1; + Vector2 point2 = line.SortingPoint2; + float deltaX = point2.x - point1.x; + if (Mathf.Abs(deltaX) <= SortingComparisonEpsilon) { + return false; + } + + float normalizedX = (x - point1.x) / deltaX; + y = point1.y + ((point2.y - point1.y) * normalizedX); + return true; + } + private static int ComparePointAndLine(Vector3 point, IsoSpriteSorting line) { float pointY = point.y; if (pointY > line.SortingPoint1.y && pointY > line.SortingPoint2.y) {