Created
November 29, 2024 13:35
-
-
Save RiskyWilhelm/b79eebea75689c5f268b48d20c55c4b3 to your computer and use it in GitHub Desktop.
Unity Extensions (C# >= 9) - My "Unity Utils" are required
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 UnityEngine; | |
public static class BoxCollider2DExtensions | |
{ | |
public static Vector2 GetRandomPoint(this BoxCollider2D a) | |
{ | |
Vector2 extents = a.bounds.extents; | |
Vector2 localPoint = new ( | |
Random.Range(-extents.x, extents.x), | |
Random.Range(-extents.y, extents.y) | |
); | |
localPoint += a.offset; | |
return a.transform.TransformPoint(localPoint); | |
} | |
} |
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 UnityEngine; | |
public static class BoxColliderExtensions | |
{ | |
public static Vector3 GetRandomPoint(this BoxCollider a) | |
{ | |
Vector3 extents = a.bounds.extents; | |
Vector3 localPoint = new ( | |
Random.Range(-extents.x, extents.x), | |
Random.Range(-extents.y, extents.y), | |
Random.Range(-extents.z, extents.z) | |
); | |
localPoint += a.center; | |
return a.transform.TransformPoint(localPoint); | |
} | |
} |
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 UnityEngine; | |
public static class CircleCollider2DExtensions | |
{ | |
public static Vector2 GetRandomPoint(this CircleCollider2D a) | |
{ | |
float radAngle = Random.Range(0, Mathf.PI * 2); | |
float distance = a.radius * Mathf.Sqrt(Random.Range(0f, 1f)); // sqrt for even distribution | |
Vector2 localPoint = new (distance * Mathf.Cos(radAngle), distance * Mathf.Sin(radAngle)); | |
localPoint += a.offset; | |
return a.transform.TransformPoint(localPoint); | |
} | |
} |
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 UnityEngine; | |
public static class Collider2DExtensions | |
{ | |
public static Vector2 GetRandomPoint(this Collider2D a) | |
{ | |
switch (a) | |
{ | |
case BoxCollider2D: | |
return (a as BoxCollider2D).GetRandomPoint(); | |
case CircleCollider2D: | |
return (a as CircleCollider2D).GetRandomPoint(); | |
} | |
Debug.LogErrorFormat("Type {0} is un-supported. BoxCollider2D and CircleCollider2D is supported only", a.GetType()); | |
return default; | |
} | |
} |
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 UnityEngine; | |
public static class ColliderExtensions | |
{ | |
public static Vector3 GetRandomPoint(this Collider a) | |
{ | |
switch (a) | |
{ | |
case BoxCollider: | |
return (a as BoxCollider).GetRandomPoint(); | |
case SphereCollider: | |
return (a as SphereCollider).GetRandomPoint(); | |
} | |
Debug.LogErrorFormat("Type {0} is un-supported. BoxCollider and SphereCollider is supported only", a.GetType()); | |
return default; | |
} | |
} |
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; | |
public static class DateTimeExtensions | |
{ | |
// TODO: Count in the Year, Month and Day | |
/// <remarks> Assumes the time 12:00 equals North(Y+ when facing to Z+) in cardinal direction. Means, degree of zero will equal to 18:00 in a circle </remarks> | |
public static float ToAngleDegree(this DateTime a, sbyte offsetHour = 0) | |
{ | |
float offsetHourDegree = (offsetHour + DateTimeUtils.DefaultOffsetHour) * DateTimeUtils.ExactHourDegree; | |
float verticallyMirroredHourDegree = 360f - (a.Hour * DateTimeUtils.ExactHourDegree); // Angle is not inverted. Mirrored the angle in a circle vertically. That way, time will grow if rotation getting negative | |
float hourDegree = verticallyMirroredHourDegree + offsetHourDegree; | |
float minuteDegree = a.Minute * DateTimeUtils.ExactMinutePoint; | |
float secondDegree = a.Second * DateTimeUtils.ExactSecondPoint; | |
return (hourDegree - minuteDegree - secondDegree) % 360f; | |
} | |
public static float ToProgress01(this DateTime a) | |
{ | |
return 1f - (a.ToAngleDegree((sbyte)-DateTimeUtils.DefaultOffsetHour) / 360f); | |
} | |
} |
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; | |
public static class EnumExtensions | |
{ | |
// TODO: Support string | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, EnumType b) | |
where EnumType : Enum | |
{ | |
// Check for the supported enum types | |
return a.GetTypeCode() switch | |
{ | |
// byte | |
TypeCode.Byte => HasAny(a, (byte)(object)b), | |
// sbyte | |
TypeCode.SByte => HasAny(a, (sbyte)(object)b), | |
// short | |
TypeCode.Int16 => HasAny(a, (short)(object)b), | |
// ushort | |
TypeCode.UInt16 => HasAny(a, (ushort)(object)b), | |
// int | |
TypeCode.Int32 => HasAny(a, (int)(object)b), | |
// uint | |
TypeCode.UInt32 => HasAny(a, (uint)(object)b), | |
// long | |
TypeCode.Int64 => HasAny(a, (long)(object)b), | |
// ulong | |
TypeCode.UInt64 => HasAny(a, (ulong)(object)b), | |
_ => throw new NotSupportedException("Unknown Error. This shouldn't be happened!"), | |
}; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, byte b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, byte>(); | |
return ((byte)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, sbyte b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, sbyte>(); | |
return ((sbyte)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, short b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, short>(); | |
return ((short)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, ushort b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, ushort>(); | |
return ((ushort)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, int b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, int>(); | |
return ((int)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, uint b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, uint>(); | |
return ((uint)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, long b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, long>(); | |
return ((long)(object)a & b) != 0; | |
} | |
/// <summary> Checks if enum 'a' contains any of the value(s) from 'b' </summary> | |
/// <remarks> Requires flag enum </remarks> | |
public static bool HasAny<EnumType>(this EnumType a, ulong b) | |
where EnumType : Enum | |
{ | |
EnumUtils.ValidateFlagEnum<EnumType>(); | |
EnumUtils.ValidateUnderlyingType<EnumType, ulong>(); | |
return ((ulong)(object)a & b) != 0; | |
} | |
} |
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; | |
public static class IEnumeratorExtensions | |
{ | |
/// <summary> Allows you to iterate through an IEnumerator </summary> | |
public static T GetEnumerator<T>(this T enumerator) | |
where T : IEnumerator | |
{ | |
return enumerator; | |
} | |
} |
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; | |
public static class RandomExtensions | |
{ | |
public static float NextFloat(this Random random, float minInclusiveValue, float maxExclusiveValue) | |
=> (float)random.NextDouble(minInclusiveValue, maxExclusiveValue); | |
public static double NextDouble(this Random random, double minInclusiveValue, double maxExclusiveValue) | |
{ | |
return random.NextDouble() * (maxExclusiveValue - minInclusiveValue) + minInclusiveValue; | |
} | |
} |
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; | |
public static class SetExtensions | |
{ | |
public static ReadOnlySet<T> AsReadOnly<T>(this ISet<T> set) | |
{ | |
return new ReadOnlySet<T>(set); | |
} | |
} |
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 UnityEngine; | |
public static class SphereColliderExtensions | |
{ | |
public static Vector3 GetRandomPoint(this SphereCollider a) | |
{ | |
Vector3 localPoint = Random.insideUnitSphere * a.radius; | |
localPoint += a.center; | |
return a.transform.TransformPoint(localPoint); | |
} | |
} |
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; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public static class TransformExtensions | |
{ | |
public static bool TryGetNearestTransform<TransformEnumeratorType>(this Transform relativeTo, TransformEnumeratorType transformEnumerator, out Transform nearestTransform, Predicate<Transform> predicateNearest = null) | |
where TransformEnumeratorType : IEnumerator<Transform> | |
{ | |
nearestTransform = default; | |
var isFoundNearest = false; | |
float nearestHorizontalDistance = float.MaxValue; | |
float iteratedDistance; | |
// Check sqr distances and select nearest | |
foreach (var iteratedTransform in transformEnumerator) | |
{ | |
iteratedDistance = (iteratedTransform.position - relativeTo.position).sqrMagnitude; | |
if ((iteratedDistance < nearestHorizontalDistance) && (predicateNearest == null || predicateNearest.Invoke(iteratedTransform))) | |
{ | |
nearestTransform = iteratedTransform; | |
nearestHorizontalDistance = iteratedDistance; | |
isFoundNearest = true; | |
} | |
} | |
return isFoundNearest; | |
} | |
} |
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 System; | |
using UnityEngine; | |
public static class VectorExtensions | |
{ | |
/// <returns> Angle in radians in PI (-180~180 Degrees) </returns> | |
public static float ToRadianAngle(this Vector2 a) | |
=> MathF.Atan2(a.y, a.x); | |
/// <returns> Angle in degrees in PI (-180~180) </returns> | |
public static float ToDegreeAngle(this Vector2 a) | |
=> MathF.Atan2(a.y, a.x) * Mathf.Rad2Deg; | |
/// <returns> Angle in radians in 2PI (0~360 Degrees) </returns> | |
public static float ToRadianAngle_360(this Vector2 a) | |
{ | |
var radian = MathF.Atan2(a.y, a.x); | |
// Same as adding 360 degree to a angle in degrees | |
if (radian < 0f) | |
radian += (Mathf.PI * 2); | |
return radian; | |
} | |
/// <returns> Angle in degrees in 2PI (0~360) </returns> | |
public static float ToDegreeAngle_360(this Vector2 a) | |
=> ToRadianAngle_360(a) * Mathf.Rad2Deg; | |
/// <returns> Non-normalized rotated original vector </returns> | |
public static Vector2 RotateByRadianAngle(this Vector2 a, float rotateAngleInRadians) | |
{ | |
return new Vector2( | |
a.x * MathF.Cos(rotateAngleInRadians) - a.y * MathF.Sin(rotateAngleInRadians), | |
a.x * MathF.Sin(rotateAngleInRadians) + a.y * MathF.Cos(rotateAngleInRadians) | |
); | |
} | |
/// <returns> Non-normalized rotated original vector </returns> | |
public static Vector2 RotateByDegreeAngle(this Vector2 a, float rotateAngleInDegrees) | |
=> RotateByRadianAngle(a, rotateAngleInDegrees * Mathf.Deg2Rad); | |
public static Vector3 RotateByDegreeAngle(this Vector3 a, float rotateAngleInDegrees, Vector3 axisToRotateAround) | |
=> Quaternion.AngleAxis(rotateAngleInDegrees, axisToRotateAround) * a; | |
/// <returns> Non-normalized rotated original vector </returns> | |
public static Vector3 RotateByRadianAngle(this Vector3 a, float rotateAngleInRadians, Vector3 axisToRotateAround) | |
=> RotateByDegreeAngle(a, rotateAngleInRadians * Mathf.Rad2Deg, axisToRotateAround); | |
public static bool TryGetNearestVector<VectorEnumeratorType>(this Vector4 relativeTo, VectorEnumeratorType vectorCollection, out Vector4 nearestVector, Predicate<Vector4> predicateNearest = null) | |
where VectorEnumeratorType : IEnumerator<Vector4> | |
{ | |
nearestVector = default; | |
var isFoundNearest = false; | |
float nearestHorizontalDistance = float.MaxValue; | |
float iteratedDistance; | |
// Check sqr distances and select nearest | |
foreach (var iteratedVector in vectorCollection) | |
{ | |
iteratedDistance = (iteratedVector - relativeTo).sqrMagnitude; | |
if ((iteratedDistance < nearestHorizontalDistance) && (predicateNearest == null || predicateNearest.Invoke(iteratedVector))) | |
{ | |
nearestVector = iteratedVector; | |
nearestHorizontalDistance = iteratedDistance; | |
isFoundNearest = true; | |
} | |
} | |
return isFoundNearest; | |
} | |
public static bool TryGetNearestVector<VectorEnumeratorType>(this Vector2 relativeTo, VectorEnumeratorType vectorCollection, out Vector2 nearestVector, Predicate<Vector2> predicateNearest = null) | |
where VectorEnumeratorType : IEnumerator<Vector2> | |
{ | |
nearestVector = default; | |
var isFoundNearest = false; | |
float nearestHorizontalDistance = float.MaxValue; | |
float iteratedDistance; | |
// Check sqr distances and select nearest | |
foreach (var iteratedVector in vectorCollection) | |
{ | |
iteratedDistance = (iteratedVector - relativeTo).sqrMagnitude; | |
if ((iteratedDistance < nearestHorizontalDistance) && (predicateNearest == null || predicateNearest.Invoke(iteratedVector))) | |
{ | |
nearestVector = iteratedVector; | |
nearestHorizontalDistance = iteratedDistance; | |
isFoundNearest = true; | |
} | |
} | |
return isFoundNearest; | |
} | |
public static bool TryGetNearestVector<VectorEnumeratorType>(this Vector3 relativeTo, VectorEnumeratorType vectorCollection, out Vector3 nearestVector, Predicate<Vector3> predicateNearest = null) | |
where VectorEnumeratorType : IEnumerator<Vector3> | |
{ | |
nearestVector = default; | |
var isFoundNearest = false; | |
float nearestHorizontalDistance = float.MaxValue; | |
float iteratedDistance; | |
// Check sqr distances and select nearest | |
foreach (var iteratedVector in vectorCollection) | |
{ | |
iteratedDistance = (iteratedVector - relativeTo).sqrMagnitude; | |
if ((iteratedDistance < nearestHorizontalDistance) && (predicateNearest == null || predicateNearest.Invoke(iteratedVector))) | |
{ | |
nearestVector = iteratedVector; | |
nearestHorizontalDistance = iteratedDistance; | |
isFoundNearest = true; | |
} | |
} | |
return isFoundNearest; | |
} | |
public static Vector3 GetDifferenceTo(this Vector3 a, Vector3 b) | |
{ | |
return (b - a); | |
} | |
public static bool IsNearTo(this Vector3 a, Vector3 b, float exceedDistance) | |
{ | |
return (b - a).sqrMagnitude <= (exceedDistance * exceedDistance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment