Last active
September 17, 2020 13:41
-
-
Save MaZyGer/b4c45395bd6a5d06722a0eecf71c850e to your computer and use it in GitHub Desktop.
This class may will be get updated after time with more functionality. OverlapCircle<T> extension will allow to use conditions and filter out directly. Example you look for collider2d but with a component like Monster and also want to check directly is monster not dead? So use this function. Check the usage how to use it. **Please Read**: The sc…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
namespace Maz.Unity.Extensions | |
{ | |
public static class MazPhysics2D | |
{ | |
#region OverlapCircle | |
/* Usage for OverlapCircle<T>: | |
Example you threw a grenade and you want to find at the position monsters with Monster Component / MonoBehavoiur and also want to filter out dead monsters. | |
List<Monster> monsters = new List<Monster>(); | |
OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { useTriggers = true }, monsters); | |
OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { useTriggers = true }, monsters, m => !m.IsDead ); | |
OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { useTriggers = true }, monsters, c => c.GetComponentInChildren<Monster>()); | |
OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { useTriggers = true }, monsters, c => c.GetComponentInChildren<Monster>(), m => m.IsDead); | |
*/ | |
/// <summary> | |
/// Same like Physics2D.OverlapCircle but it will look for T Component | |
/// </summary> | |
/// <typeparam name="T">Component you looking for Example: MeshRenderer</typeparam> | |
/// <param name="pos"></param> | |
/// <param name="radius"></param> | |
/// <param name="contactFilter2D"></param> | |
/// <param name="foundTargets"></param> | |
/// <returns></returns> | |
public static int OverlapCircle<T>(Vector2 pos, float radius, ContactFilter2D contactFilter2D, List<T> foundTargets) | |
{ | |
List<Collider2D> collider2Ds = new List<Collider2D>(); | |
int count = 0; | |
if (Physics2D.OverlapCircle(pos, radius, contactFilter2D, collider2Ds) > 0) | |
{ | |
foreach (var c in collider2Ds) | |
{ | |
if (c.TryGetComponent(out T t)) | |
{ | |
count++; | |
foundTargets.Add(t); | |
} | |
} | |
} | |
return count; | |
} | |
/// <summary> | |
/// Same like Physics2D.OverlapCircle but it will look for T Component and will return only colliders with condition is true | |
/// </summary> | |
/// <typeparam name="T">Component you looking for Example: MeshRenderer</typeparam> | |
/// <param name="pos"></param> | |
/// <param name="radius"></param> | |
/// <param name="contactFilter2D"></param> | |
/// <param name="foundTargets"></param> | |
/// <param name="condition">If the condition is true it collider will be added to the list</param> | |
/// <returns></returns> | |
public static int OverlapCircle<T>(Vector2 pos, float radius, ContactFilter2D contactFilter2D, List<T> foundTargets, System.Func<T, bool> condition) | |
{ | |
List<Collider2D> collider2Ds = new List<Collider2D>(); | |
int count = 0; | |
if (Physics2D.OverlapCircle(pos, radius, contactFilter2D, collider2Ds) > 0) | |
{ | |
foreach (var c in collider2Ds) | |
{ | |
if (c.TryGetComponent(out T t)) | |
{ | |
var res = condition.Invoke(t); | |
if (res) | |
{ | |
count++; | |
foundTargets.Add(t); | |
} | |
} | |
} | |
} | |
return count; | |
} | |
/// <summary> | |
/// Same like Physics2D.OverlapCircle but it will look for T Component and will return only colliders with condition is true | |
/// </summary> | |
/// <typeparam name="T">Component you looking for Example: MeshRenderer</typeparam> | |
/// <param name="pos"></param> | |
/// <param name="radius"></param> | |
/// <param name="contactFilter2D"></param> | |
/// <param name="foundTargets"></param> | |
/// <param name="ComponentCondition">Custom GetComponent condition. Example if you want to use GetComponentInChildren</param> | |
/// <returns></returns> | |
public static int OverlapCircle<T>(Vector2 pos, float radius, ContactFilter2D contactFilter2D, List<T> foundTargets, System.Func<Collider2D, T> ComponentCondition) | |
{ | |
List<Collider2D> collider2Ds = new List<Collider2D>(); | |
int count = 0; | |
if (Physics2D.OverlapCircle(pos, radius, contactFilter2D, collider2Ds) > 0) | |
{ | |
foreach (var c in collider2Ds) | |
{ | |
T t; | |
if ((t = ComponentCondition.Invoke(c)) != null) | |
{ | |
count++; | |
foundTargets.Add(t); | |
} | |
} | |
} | |
return count; | |
} | |
/// <summary> | |
/// Same like Physics2D.OverlapCircle but it will look for T Component and will return only colliders with condition is true | |
/// </summary> | |
/// <typeparam name="T">Component you looking for Example: MeshRenderer</typeparam> | |
/// <param name="pos"></param> | |
/// <param name="radius"></param> | |
/// <param name="contactFilter2D"></param> | |
/// <param name="foundTargets"></param> | |
/// <param name="ComponentCondition">Custom GetComponent condition. Example if you want to use GetComponentInChildren</param> | |
/// <param name="condition">If the condition is true it collider will be added to the list</param> | |
/// <returns></returns> | |
public static int OverlapCircle<T>(Vector2 pos, float radius, ContactFilter2D contactFilter2D, List<T> foundTargets, System.Func<Collider2D, T> ComponentCondition, System.Func<T, bool> condition) | |
{ | |
List<Collider2D> collider2Ds = new List<Collider2D>(); | |
int count = 0; | |
if (Physics2D.OverlapCircle(pos, radius, contactFilter2D, collider2Ds) > 0) | |
{ | |
foreach (var c in collider2Ds) | |
{ | |
T t; | |
if ((t = ComponentCondition.Invoke(c)) != null) | |
{ | |
var res = condition.Invoke(t); | |
if (res) | |
{ | |
count++; | |
foundTargets.Add(t); | |
} | |
} | |
} | |
} | |
return count; | |
} | |
#endregion | |
} | |
public static class MazPhysics | |
{ | |
public static bool Raycast<T>(Ray ray, float maxDistance, out T obj) | |
{ | |
RaycastHit hit; | |
obj = default(T); | |
if (UnityEngine.Physics.Raycast(ray, out hit, maxDistance)) | |
{ | |
if (hit.transform.TryGetComponent(out T tmp)) | |
{ | |
obj = tmp; | |
return true; | |
} | |
} | |
return false; | |
} | |
public static bool SphereNearest<T>(Ray ray, float radius, out T obj) | |
{ | |
obj = default(T); | |
RaycastHit[] raycastHits = new RaycastHit[5]; | |
if (UnityEngine.Physics.SphereCastNonAlloc(ray, radius, raycastHits) > 0) | |
{ | |
System.Array.Sort(raycastHits, (hit1, hit2) => | |
{ | |
if (hit1.transform == null || hit2.transform == null) | |
return 99; | |
var dist1 = Vector3.Distance(ray.origin, hit1.transform.position); | |
var dist2 = Vector3.Distance(ray.origin, hit2.transform.position); | |
return dist1.CompareTo(dist2); | |
}); | |
foreach (var hit in raycastHits) | |
{ | |
if (hit.transform == null) | |
continue; | |
if (hit.transform.TryGetComponent(out obj)) | |
{ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment