Skip to content

Instantly share code, notes, and snippets.

@MaZyGer
Last active September 17, 2020 13:41
Show Gist options
  • Save MaZyGer/b4c45395bd6a5d06722a0eecf71c850e to your computer and use it in GitHub Desktop.
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…
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