본문 바로가기
개발/유니티 (Unity)

유니티 Physics.SphereCastAll 정렬하기.

by 레조 2024. 5. 15.

평행 포탑

 

RaycastHit[] hitList = Physics.SphereCastAll(...)

 

얼마전 관통형 무기 구현에서 벽 감지에 문제가 있었습니다.
레이저 빔을 맞은 대상 리스트가 정렬되지 않음.

 

참고 : SphereCastAll, SphereCastNonAlloc

https://www.youtube.com/watch?v=W579Mdi1Az4

 

이 영상만 보면 순서대로 잘 나옵니다.

 

왜?

 

순서대로 부딪혔으니까... OTL...

 

사용중인 MIT License 코드를 간소하게 수정

public static class PhysicsExtensions
{
	private class AscendingDistanceComparer : IComparer<RaycastHit>
	{
		public int Compare(RaycastHit h1, RaycastHit h2)
		{
			return h1.distance < h2.distance ? -1 : (h1.distance > h2.distance ? 1 : 0);
		}
	}

	private static AscendingDistanceComparer ascendDistance = new AscendingDistanceComparer();

	public static void SortClosestToFurthest(RaycastHit[] hits)
	{
		if (hits.Length < 2) return;
		Array.Sort<RaycastHit>(hits, 0, hits.Length, ascendDistance);
	}
}

 

이제 사용후 정렬하면 OK.

RaycastHit[] hitList = Physics.SphereCastAll(...);
PhysicsExtensions.SortClosestToFurthest(hitList);

 

벽 레이어가 마지막에 잘 감지됨.

 

추가.

폭발형 무기의 타겟 정렬.

물론 순서 관계 없는 폭발이면 정렬도 필요없다.

 

Physics.OverlapSphere, LINQ 사용.

// https://stackoverflow.com/questions/59505652/is-there-a-specific-order-to-the-colliders-that-physics-overlapsphere-returns
Collider[] cols = Physics.OverlapSphere(center, radius);
var newCols = cols.OrderBy(c => Vector3.Distance(center, c.transform.position)).ToArray();