using System.Collections.Generic; using UnityEngine; namespace Lightbug.Utilities { public delegate bool HitFilterDelegate(Transform hitTransform); public delegate bool Hit2DFilterDelegate(ref RaycastHit2D hitInfo); public delegate bool Hit3DFilterDelegate(ref RaycastHit hitInfo); public delegate bool OverlapFilterDelegate2D(Collider2D collider); public delegate bool OverlapFilterDelegate3D(Collider collider); public static class PhysicsExtensions { public enum ClosestHitResult { NoHit, Hit, Overlap } public static ClosestHitResult GetFurthestHit(this RaycastHit[] array, out RaycastHit hitInfo, int length, Hit3DFilterDelegate filter) { float closestDistance = 0f; int index = -1; hitInfo = new RaycastHit(); if (length == 0) return ClosestHitResult.NoHit; for (int i = 0; i < length; i++) { var h = array[i]; if (filter != null) if (!filter.Invoke(ref h)) continue; if (h.distance > closestDistance) { closestDistance = h.distance; index = i; } } bool hit = index != -1; if (hit) { hitInfo = array[index]; return ClosestHitResult.Hit; } return ClosestHitResult.NoHit; } public static ClosestHitResult GetFurthestHit(this RaycastHit2D[] array, out RaycastHit2D hitInfo, int length, Hit2DFilterDelegate filter) { float closestDistance = 0f; int index = -1; hitInfo = new RaycastHit2D(); if (length == 0) return ClosestHitResult.NoHit; for (int i = 0; i < length; i++) { var h = array[i]; if (filter != null) if (!filter.Invoke(ref h)) continue; if (h.distance > closestDistance) { closestDistance = h.distance; index = i; } } bool hit = index != -1; if (hit) { hitInfo = array[index]; return ClosestHitResult.Hit; } return ClosestHitResult.NoHit; } public static ClosestHitResult GetClosestHit(this RaycastHit[] array, out RaycastHit hitInfo, int length, Hit3DFilterDelegate filter) { float closestDistance = Mathf.Infinity; int index = -1; hitInfo = new RaycastHit(); if (length == 0) return ClosestHitResult.NoHit; for (int i = 0; i < length; i++) { var h = array[i]; if (filter != null) if (!filter.Invoke(ref h)) continue; if (h.distance < closestDistance) { closestDistance = h.distance; index = i; } } bool hit = index != -1; if (hit) { hitInfo = array[index]; return ClosestHitResult.Hit; } return ClosestHitResult.NoHit; } public static ClosestHitResult GetClosestHit(this RaycastHit2D[] array, out RaycastHit2D hitInfo, int length, Hit2DFilterDelegate filter) { float closestDistance = Mathf.Infinity; int index = -1; hitInfo = new RaycastHit2D(); if (length == 0) return ClosestHitResult.NoHit; for (int i = 0; i < length; i++) { var h = array[i]; if (filter != null) if (!filter.Invoke(ref h)) continue; if (h.distance < closestDistance) { closestDistance = h.distance; index = i; } } bool hit = index != -1; if (hit) { hitInfo = array[index]; return ClosestHitResult.Hit; } return ClosestHitResult.NoHit; } } }