Created
July 10, 2017 02:05
-
-
Save JakubNei/e4741fc9c26b016854179199358ac052 to your computer and use it in GitHub Desktop.
Collection of useful Unity3D extensions I've made over the years. I usually carry this to any project I work on.
This file contains 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; | |
/// <summary> | |
/// Version: 2017-07-06 (yyyy-MM-dd) | |
/// Many useful Unity3D extensions I've made over the years. | |
/// All in one class. | |
/// </summary> | |
public static class NeitriUnityExtensions | |
{ | |
#region Vector2 extensions | |
public static Vector2 Closest(this IEnumerable<Vector2> vecEnum, Vector2 closestTo) | |
{ | |
var closestDist = float.MaxValue; | |
var closestElem = closestTo; | |
foreach (var currentElem in vecEnum) | |
{ | |
var currentDistance = currentElem.DistanceSqr(closestTo); | |
if (currentDistance < closestDist) | |
{ | |
closestDist = currentDistance; | |
closestElem = currentElem; | |
} | |
} | |
return closestElem; | |
} | |
public static Vector2 LerpTo(this Vector2 me, Vector2 towards, float t) | |
{ | |
return Vector2.Lerp(me, towards, t); | |
} | |
public static Vector2 Round(this Vector2 me) | |
{ | |
return new Vector2(me.x.Round(), me.y.Round()); | |
} | |
public static Vector2 Ceil(this Vector2 me) | |
{ | |
return new Vector2(me.x.Ceil(), me.y.Ceil()); | |
} | |
public static Vector2 Floor(this Vector2 me) | |
{ | |
return new Vector2(me.x.Floor(), me.y.Floor()); | |
} | |
public static float DistanceSqr(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
return (me - other).sqrMagnitude; | |
} | |
public static float Distance(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
return UnityEngine.Vector2.Distance(me, other); | |
} | |
public static float Dot(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
return UnityEngine.Vector2.Dot(me, other); | |
} | |
public static float Angle(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
return UnityEngine.Vector2.Angle(me, other); | |
} | |
public static Vector2 Divide(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
me.Scale(new UnityEngine.Vector2(1 / other.x, 1 / other.y)); | |
return me; | |
} | |
public static Vector2 Multiply(this UnityEngine.Vector2 me, UnityEngine.Vector2 other) | |
{ | |
me.Scale(other); | |
return me; | |
} | |
public static Vector2 Normalized(this UnityEngine.Vector2 me) | |
{ | |
return me.normalized; | |
} | |
public static float SqrMagnitude(this UnityEngine.Vector2 me) | |
{ | |
return me.sqrMagnitude; | |
} | |
public static float Magnitude(this UnityEngine.Vector2 me) | |
{ | |
return me.magnitude; | |
} | |
public static Vector2 Towards(this UnityEngine.Vector2 from, UnityEngine.Vector2 to) | |
{ | |
return to - from; | |
} | |
public static Vector2 SetX(this Vector2 target, float newX) | |
{ | |
target.x = newX; | |
return target; | |
} | |
public static Vector2 SetY(this Vector2 target, float newY) | |
{ | |
target.y = newY; | |
return target; | |
} | |
public static Vector2 AddX(this Vector2 target, float addX) | |
{ | |
target.x += addX; | |
return target; | |
} | |
public static Vector2 AddY(this Vector2 target, float addY) | |
{ | |
target.y += addY; | |
return target; | |
} | |
/* | |
javascript code to generate all the To Vector3 combinations, open Chrome web browser press f12, paste the code, press enter, done, copy paste here | |
var names = ["X","Y","0","1"]; | |
var returns = ["me.x","me.y","0","1"]; | |
var ret="\n\n"; | |
names.forEach(function(value1, index1){ | |
names.forEach(function(value2, index2){ | |
names.forEach(function(value3, index3){ | |
ret += "public static Vector3 To"+value1+value2+value3+"(this Vector2 me) { return new Vector3("+returns[index1]+", "+returns[index2]+", "+returns[index3]+"); }\n"; | |
}); | |
}); | |
}); | |
ret+"\n\n" | |
*/ | |
public static Vector3 ToXXX(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.x, me.x); | |
} | |
public static Vector3 ToXXY(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.x, me.y); | |
} | |
public static Vector3 ToXX0(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.x, 0); | |
} | |
public static Vector3 ToXX1(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.x, 1); | |
} | |
public static Vector3 ToXYX(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.y, me.x); | |
} | |
public static Vector3 ToXYY(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.y, me.y); | |
} | |
public static Vector3 ToXY0(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.y, 0); | |
} | |
public static Vector3 ToXY1(this Vector2 me) | |
{ | |
return new Vector3(me.x, me.y, 1); | |
} | |
public static Vector3 ToX0X(this Vector2 me) | |
{ | |
return new Vector3(me.x, 0, me.x); | |
} | |
public static Vector3 ToX0Y(this Vector2 me) | |
{ | |
return new Vector3(me.x, 0, me.y); | |
} | |
public static Vector3 ToX00(this Vector2 me) | |
{ | |
return new Vector3(me.x, 0, 0); | |
} | |
public static Vector3 ToX01(this Vector2 me) | |
{ | |
return new Vector3(me.x, 0, 1); | |
} | |
public static Vector3 ToX1X(this Vector2 me) | |
{ | |
return new Vector3(me.x, 1, me.x); | |
} | |
public static Vector3 ToX1Y(this Vector2 me) | |
{ | |
return new Vector3(me.x, 1, me.y); | |
} | |
public static Vector3 ToX10(this Vector2 me) | |
{ | |
return new Vector3(me.x, 1, 0); | |
} | |
public static Vector3 ToX11(this Vector2 me) | |
{ | |
return new Vector3(me.x, 1, 1); | |
} | |
public static Vector3 ToYXX(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.x, me.x); | |
} | |
public static Vector3 ToYXY(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.x, me.y); | |
} | |
public static Vector3 ToYX0(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.x, 0); | |
} | |
public static Vector3 ToYX1(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.x, 1); | |
} | |
public static Vector3 ToYYX(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.y, me.x); | |
} | |
public static Vector3 ToYYY(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.y, me.y); | |
} | |
public static Vector3 ToYY0(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.y, 0); | |
} | |
public static Vector3 ToYY1(this Vector2 me) | |
{ | |
return new Vector3(me.y, me.y, 1); | |
} | |
public static Vector3 ToY0X(this Vector2 me) | |
{ | |
return new Vector3(me.y, 0, me.x); | |
} | |
public static Vector3 ToY0Y(this Vector2 me) | |
{ | |
return new Vector3(me.y, 0, me.y); | |
} | |
public static Vector3 ToY00(this Vector2 me) | |
{ | |
return new Vector3(me.y, 0, 0); | |
} | |
public static Vector3 ToY01(this Vector2 me) | |
{ | |
return new Vector3(me.y, 0, 1); | |
} | |
public static Vector3 ToY1X(this Vector2 me) | |
{ | |
return new Vector3(me.y, 1, me.x); | |
} | |
public static Vector3 ToY1Y(this Vector2 me) | |
{ | |
return new Vector3(me.y, 1, me.y); | |
} | |
public static Vector3 ToY10(this Vector2 me) | |
{ | |
return new Vector3(me.y, 1, 0); | |
} | |
public static Vector3 ToY11(this Vector2 me) | |
{ | |
return new Vector3(me.y, 1, 1); | |
} | |
public static Vector3 To0XX(this Vector2 me) | |
{ | |
return new Vector3(0, me.x, me.x); | |
} | |
public static Vector3 To0XY(this Vector2 me) | |
{ | |
return new Vector3(0, me.x, me.y); | |
} | |
public static Vector3 To0X0(this Vector2 me) | |
{ | |
return new Vector3(0, me.x, 0); | |
} | |
public static Vector3 To0X1(this Vector2 me) | |
{ | |
return new Vector3(0, me.x, 1); | |
} | |
public static Vector3 To0YX(this Vector2 me) | |
{ | |
return new Vector3(0, me.y, me.x); | |
} | |
public static Vector3 To0YY(this Vector2 me) | |
{ | |
return new Vector3(0, me.y, me.y); | |
} | |
public static Vector3 To0Y0(this Vector2 me) | |
{ | |
return new Vector3(0, me.y, 0); | |
} | |
public static Vector3 To0Y1(this Vector2 me) | |
{ | |
return new Vector3(0, me.y, 1); | |
} | |
public static Vector3 To00X(this Vector2 me) | |
{ | |
return new Vector3(0, 0, me.x); | |
} | |
public static Vector3 To00Y(this Vector2 me) | |
{ | |
return new Vector3(0, 0, me.y); | |
} | |
public static Vector3 To000(this Vector2 me) | |
{ | |
return new Vector3(0, 0, 0); | |
} | |
public static Vector3 To001(this Vector2 me) | |
{ | |
return new Vector3(0, 0, 1); | |
} | |
public static Vector3 To01X(this Vector2 me) | |
{ | |
return new Vector3(0, 1, me.x); | |
} | |
public static Vector3 To01Y(this Vector2 me) | |
{ | |
return new Vector3(0, 1, me.y); | |
} | |
public static Vector3 To010(this Vector2 me) | |
{ | |
return new Vector3(0, 1, 0); | |
} | |
public static Vector3 To011(this Vector2 me) | |
{ | |
return new Vector3(0, 1, 1); | |
} | |
public static Vector3 To1XX(this Vector2 me) | |
{ | |
return new Vector3(1, me.x, me.x); | |
} | |
public static Vector3 To1XY(this Vector2 me) | |
{ | |
return new Vector3(1, me.x, me.y); | |
} | |
public static Vector3 To1X0(this Vector2 me) | |
{ | |
return new Vector3(1, me.x, 0); | |
} | |
public static Vector3 To1X1(this Vector2 me) | |
{ | |
return new Vector3(1, me.x, 1); | |
} | |
public static Vector3 To1YX(this Vector2 me) | |
{ | |
return new Vector3(1, me.y, me.x); | |
} | |
public static Vector3 To1YY(this Vector2 me) | |
{ | |
return new Vector3(1, me.y, me.y); | |
} | |
public static Vector3 To1Y0(this Vector2 me) | |
{ | |
return new Vector3(1, me.y, 0); | |
} | |
public static Vector3 To1Y1(this Vector2 me) | |
{ | |
return new Vector3(1, me.y, 1); | |
} | |
public static Vector3 To10X(this Vector2 me) | |
{ | |
return new Vector3(1, 0, me.x); | |
} | |
public static Vector3 To10Y(this Vector2 me) | |
{ | |
return new Vector3(1, 0, me.y); | |
} | |
public static Vector3 To100(this Vector2 me) | |
{ | |
return new Vector3(1, 0, 0); | |
} | |
public static Vector3 To101(this Vector2 me) | |
{ | |
return new Vector3(1, 0, 1); | |
} | |
public static Vector3 To11X(this Vector2 me) | |
{ | |
return new Vector3(1, 1, me.x); | |
} | |
public static Vector3 To11Y(this Vector2 me) | |
{ | |
return new Vector3(1, 1, me.y); | |
} | |
public static Vector3 To110(this Vector2 me) | |
{ | |
return new Vector3(1, 1, 0); | |
} | |
public static Vector3 To111(this Vector2 me) | |
{ | |
return new Vector3(1, 1, 1); | |
} | |
#endregion | |
#region Vector3 extensions | |
public static Vector3 Closest(this IEnumerable<Vector3> vecEnum, Vector3 closestTo) | |
{ | |
var closestDist = float.MaxValue; | |
var closestElem = closestTo; | |
foreach (var currentElem in vecEnum) | |
{ | |
var currentDistance = currentElem.DistanceSqr(closestTo); | |
if (currentDistance < closestDist) | |
{ | |
closestDist = currentDistance; | |
closestElem = currentElem; | |
} | |
} | |
return closestElem; | |
} | |
public static Vector3 LerpTo(this Vector3 me, Vector3 towards, float t) | |
{ | |
return Vector3.Lerp(me, towards, t); | |
} | |
public static Vector3 SlerpTo(this Vector3 me, Vector3 towards, float t) | |
{ | |
return Vector3.Slerp(me, towards, t); | |
} | |
public static Vector3 Reflect(this Vector3 me, Vector3 byNormal) | |
{ | |
return Vector3.Reflect(me, byNormal); | |
} | |
public static Vector3 Round(this Vector3 me) | |
{ | |
return new Vector3(me.x.Round(), me.y.Round(), me.z.Round()); | |
} | |
public static Vector3 Ceil(this Vector3 me) | |
{ | |
return new Vector3(me.x.Ceil(), me.y.Ceil(), me.z.Ceil()); | |
} | |
public static Vector3 Floor(this Vector3 me) | |
{ | |
return new Vector3(me.x.Floor(), me.y.Floor(), me.z.Floor()); | |
} | |
public static float DistanceSqr(this Vector3 me, Vector3 other) | |
{ | |
return (me - other).sqrMagnitude; | |
} | |
public static float Distance(this Vector3 me, Vector3 other) | |
{ | |
return Vector3.Distance(me, other); | |
} | |
public static float Dot(this Vector3 me, Vector3 other) | |
{ | |
return Vector3.Dot(me, other); | |
} | |
/// <summary> | |
/// Returns the angle in degrees between <paramref name="from"/> and <paramref name="to"/>. | |
/// </summary> | |
/// <param name="from"></param> | |
/// <param name="to"></param> | |
/// <returns></returns> | |
public static float Angle(this Vector3 from, Vector3 to) | |
{ | |
return Vector3.Angle(from, to); | |
} | |
public static Quaternion LookRot(this Vector3 me) | |
{ | |
if (me.sqrMagnitude > 0) return Quaternion.LookRotation(me); | |
return Quaternion.LookRotation(Vector3.forward); | |
} | |
public static Quaternion LookRot(this Vector3 me, Vector3 vectorUp) | |
{ | |
if (me.sqrMagnitude > 0) return Quaternion.LookRotation(me, vectorUp); | |
return Quaternion.LookRotation(Vector3.forward, vectorUp); | |
} | |
public static Quaternion Euler(this Vector3 me) | |
{ | |
return Quaternion.Euler(me); | |
} | |
/// <summary> | |
/// Divides each number of the vector. result_i = me_i / other_i | |
/// </summary> | |
/// <param name="me"></param> | |
/// <param name="other"></param> | |
/// <returns></returns> | |
public static Vector3 Divide(this Vector3 me, Vector3 other) | |
{ | |
me.Scale(new Vector3(1 / other.x, 1 / other.y, 1 / other.z)); | |
return me; | |
} | |
/// <summary> | |
/// Multiplies each number of the vector. result_i = me_i * other_i | |
/// </summary> | |
/// <param name="me"></param> | |
/// <param name="other"></param> | |
/// <returns></returns> | |
public static Vector3 Multiply(this Vector3 me, Vector3 other) | |
{ | |
me.Scale(other); | |
return me; | |
} | |
public static Vector3 Normalized(this Vector3 me) | |
{ | |
return me.normalized; | |
} | |
public static float SqrMagnitude(this Vector3 me) | |
{ | |
return me.sqrMagnitude; | |
} | |
public static float Magnitude(this Vector3 me) | |
{ | |
return me.magnitude; | |
} | |
public static Vector3 Cross(this Vector3 me, Vector3 other) | |
{ | |
return Vector3.Cross(me, other); | |
} | |
public static Vector3 Towards(this Vector3 from, Vector3 to) | |
{ | |
return to - from; | |
} | |
public static Vector3 SetX(this Vector3 target, float newX) | |
{ | |
target.x = newX; | |
return target; | |
} | |
public static Vector3 SetY(this Vector3 target, float newY) | |
{ | |
target.y = newY; | |
return target; | |
} | |
public static Vector3 SetZ(this Vector3 target, float newZ) | |
{ | |
target.z = newZ; | |
return target; | |
} | |
public static Vector3 AddX(this Vector3 target, float addX) | |
{ | |
target.x += addX; | |
return target; | |
} | |
public static Vector3 AddY(this Vector3 target, float addY) | |
{ | |
target.y += addY; | |
return target; | |
} | |
public static Vector3 AddZ(this Vector3 target, float addZ) | |
{ | |
target.z -= addZ; | |
return target; | |
} | |
/* | |
javascript code to generate all the To Vector2 combinations, open Chrome web browser press f12, paste the code, press enter, done, copy paste here | |
var names = ["X","Y","Z","0","1"]; | |
var returns = ["me.x","me.y","me.z","0","1"]; | |
var ret="\n\n"; | |
names.forEach(function(value1, index1){ | |
names.forEach(function(value2, index2){ | |
ret += "public static Vector2 To"+value1+value2+"(this Vector3 me) { return new Vector2("+returns[index1]+", "+returns[index2]+"); }\n"; | |
}); | |
}); | |
ret+"\n\n" | |
*/ | |
public static Vector2 ToXX(this Vector3 me) | |
{ | |
return new Vector2(me.x, me.x); | |
} | |
public static Vector2 ToXY(this Vector3 me) | |
{ | |
return new Vector2(me.x, me.y); | |
} | |
public static Vector2 ToXZ(this Vector3 me) | |
{ | |
return new Vector2(me.x, me.z); | |
} | |
public static Vector2 ToX0(this Vector3 me) | |
{ | |
return new Vector2(me.x, 0); | |
} | |
public static Vector2 ToX1(this Vector3 me) | |
{ | |
return new Vector2(me.x, 1); | |
} | |
public static Vector2 ToYX(this Vector3 me) | |
{ | |
return new Vector2(me.y, me.x); | |
} | |
public static Vector2 ToYY(this Vector3 me) | |
{ | |
return new Vector2(me.y, me.y); | |
} | |
public static Vector2 ToYZ(this Vector3 me) | |
{ | |
return new Vector2(me.y, me.z); | |
} | |
public static Vector2 ToY0(this Vector3 me) | |
{ | |
return new Vector2(me.y, 0); | |
} | |
public static Vector2 ToY1(this Vector3 me) | |
{ | |
return new Vector2(me.y, 1); | |
} | |
public static Vector2 ToZX(this Vector3 me) | |
{ | |
return new Vector2(me.z, me.x); | |
} | |
public static Vector2 ToZY(this Vector3 me) | |
{ | |
return new Vector2(me.z, me.y); | |
} | |
public static Vector2 ToZZ(this Vector3 me) | |
{ | |
return new Vector2(me.z, me.z); | |
} | |
public static Vector2 ToZ0(this Vector3 me) | |
{ | |
return new Vector2(me.z, 0); | |
} | |
public static Vector2 ToZ1(this Vector3 me) | |
{ | |
return new Vector2(me.z, 1); | |
} | |
public static Vector2 To0X(this Vector3 me) | |
{ | |
return new Vector2(0, me.x); | |
} | |
public static Vector2 To0Y(this Vector3 me) | |
{ | |
return new Vector2(0, me.y); | |
} | |
public static Vector2 To0Z(this Vector3 me) | |
{ | |
return new Vector2(0, me.z); | |
} | |
public static Vector2 To00(this Vector3 me) | |
{ | |
return new Vector2(0, 0); | |
} | |
public static Vector2 To01(this Vector3 me) | |
{ | |
return new Vector2(0, 1); | |
} | |
public static Vector2 To1X(this Vector3 me) | |
{ | |
return new Vector2(1, me.x); | |
} | |
public static Vector2 To1Y(this Vector3 me) | |
{ | |
return new Vector2(1, me.y); | |
} | |
public static Vector2 To1Z(this Vector3 me) | |
{ | |
return new Vector2(1, me.z); | |
} | |
public static Vector2 To10(this Vector3 me) | |
{ | |
return new Vector2(1, 0); | |
} | |
public static Vector2 To11(this Vector3 me) | |
{ | |
return new Vector2(1, 1); | |
} | |
#endregion | |
#region IEnumerable<Vector3> extensions | |
public static void DrawGizmos(this IEnumerable<Vector3> vectorPath) | |
{ | |
vectorPath.DrawGizmos(new Color(0, 1F, 0, 1F)); | |
} | |
public static void DrawGizmos(this IEnumerable<Vector3> vectorPath, Color color) | |
{ | |
Gizmos.color = color; | |
var e = vectorPath.GetEnumerator(); | |
if (!e.MoveNext()) return; | |
var last = e.Current; | |
while (e.MoveNext()) | |
{ | |
var current = e.Current; | |
Gizmos.DrawLine(last, current); | |
last = current; | |
} | |
} | |
public static float Length(this IEnumerable<Vector3> vectorPath) | |
{ | |
float distance = 0; | |
var e = vectorPath.GetEnumerator(); | |
if (!e.MoveNext()) return distance; | |
var last = e.Current; | |
while (e.MoveNext()) | |
{ | |
var current = e.Current; | |
distance += last.Distance(current); | |
last = current; | |
} | |
return distance; | |
} | |
#endregion | |
#region IEnumerable<Collider> extensions | |
public static CollidersState GetCollidersState(this IEnumerable<Collider> colliders) | |
{ | |
return new CollidersState(colliders); | |
} | |
public static void IgnoreCollision(this IEnumerable<Collider> colliders, IEnumerable<Collider> others, bool ignore) | |
{ | |
foreach (var me in colliders) | |
{ | |
foreach (var other in others) | |
{ | |
UnityEngine.Physics.IgnoreCollision(me, other, ignore); | |
} | |
} | |
} | |
#endregion | |
#region Quaternion extensions | |
static bool IsFloatSane(float f) | |
{ | |
return !(float.IsInfinity(f) || float.IsNaN(f)); | |
} | |
public static bool IsSane(this Quaternion me) | |
{ | |
return me.w != 0 && IsFloatSane(me.x) && IsFloatSane(me.y) && IsFloatSane(me.z) && IsFloatSane(me.w); | |
} | |
public static Quaternion Inverse(this Quaternion me) | |
{ | |
return Quaternion.Inverse(me); | |
} | |
#endregion | |
#region Bounds extensions | |
// http://answers.unity3d.com/questions/29797/how-to-get-8-vertices-from-bounds-properties.html | |
public static Vector3[] GetCorners(this MyBounds bounds) | |
{ | |
var boundPoint1 = bounds.min; | |
var boundPoint2 = bounds.max; | |
return new[] { | |
boundPoint1, | |
boundPoint2, | |
new Vector3(boundPoint1.x, boundPoint1.y, boundPoint2.z), | |
new Vector3(boundPoint1.x, boundPoint2.y, boundPoint1.z), | |
new Vector3(boundPoint2.x, boundPoint1.y, boundPoint1.z), | |
new Vector3(boundPoint1.x, boundPoint2.y, boundPoint2.z), | |
new Vector3(boundPoint2.x, boundPoint1.y, boundPoint2.z), | |
new Vector3(boundPoint2.x, boundPoint2.y, boundPoint1.z), | |
}; | |
} | |
#endregion | |
#region RectTransform extensions | |
public static float GetLocalHeight(this RectTransform rect) | |
{ | |
var corners = new Vector3[4]; | |
rect.GetLocalCorners(corners); | |
return Mathf.Abs(corners[0].y - corners[2].y); | |
} | |
public static float GetLocalWidth(this RectTransform rect) | |
{ | |
var corners = new Vector3[4]; | |
rect.GetLocalCorners(corners); | |
return Mathf.Abs(corners[0].x - corners[2].x); | |
} | |
#endregion | |
#region System.Random extensions | |
public static Vector3 InsideUnitSphere(this System.Random random) | |
{ | |
var result = new Vector3(random.Next(-1, 1), random.Next(-1, 1), random.Next(-1, 1)); | |
return result.normalized; | |
} | |
public static Vector2 InsideUnitCircle(this System.Random random) | |
{ | |
var result = new Vector2(random.Next(-1, 1), random.Next(-1, 1)); | |
return result.normalized; | |
} | |
#endregion | |
#region Mesh extensions | |
public static void RecalculateTangents(this Mesh theMesh) | |
{ | |
int vertexCount = theMesh.vertexCount; | |
Vector3[] vertices = theMesh.vertices; | |
Vector3[] normals = theMesh.normals; | |
UnityEngine.Vector2[] texcoords = theMesh.uv; | |
if (vertices.Length <= 0 || normals.Length <= 0 || texcoords.Length <= 0) throw new System.Exception("vertices normals or uvs are empty"); | |
int[] triangles = theMesh.triangles; | |
int triangleCount = triangles.Length / 3; | |
Vector4[] tangents = new Vector4[vertexCount]; | |
Vector3[] tan1 = new Vector3[vertexCount]; | |
Vector3[] tan2 = new Vector3[vertexCount]; | |
int tri = 0; | |
for (int i = 0; i < (triangleCount); i++) | |
{ | |
int i1 = triangles[tri]; | |
int i2 = triangles[tri + 1]; | |
int i3 = triangles[tri + 2]; | |
Vector3 v1 = vertices[i1]; | |
Vector3 v2 = vertices[i2]; | |
Vector3 v3 = vertices[i3]; | |
UnityEngine.Vector2 w1 = texcoords[i1]; | |
UnityEngine.Vector2 w2 = texcoords[i2]; | |
UnityEngine.Vector2 w3 = texcoords[i3]; | |
float x1 = v2.x - v1.x; | |
float x2 = v3.x - v1.x; | |
float y1 = v2.y - v1.y; | |
float y2 = v3.y - v1.y; | |
float z1 = v2.z - v1.z; | |
float z2 = v3.z - v1.z; | |
float s1 = w2.x - w1.x; | |
float s2 = w3.x - w1.x; | |
float t1 = w2.y - w1.y; | |
float t2 = w3.y - w1.y; | |
float r = 1.0f / (s1 * t2 - s2 * t1); | |
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); | |
Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); | |
tan1[i1] += sdir; | |
tan1[i2] += sdir; | |
tan1[i3] += sdir; | |
tan2[i1] += tdir; | |
tan2[i2] += tdir; | |
tan2[i3] += tdir; | |
tri += 3; | |
} | |
for (int i = 0; i < (vertexCount); i++) | |
{ | |
Vector3 n = normals[i]; | |
Vector3 t = tan1[i]; | |
// Gram-Schmidt orthogonalize | |
Vector3.OrthoNormalize(ref n, ref t); | |
tangents[i].x = t.x; | |
tangents[i].y = t.y; | |
tangents[i].z = t.z; | |
// Calculate handedness | |
tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f; | |
} | |
theMesh.tangents = tangents; | |
} | |
#endregion | |
#region GameObject extensions | |
/// <summary> | |
/// Gets all components in the component's transfrom hiearchy | |
/// </summary> | |
/// <param name="component"></param> | |
/// <param name="type">Can be any interface or UnityEngine.Component</param> | |
/// <returns></returns> | |
public static TYPE[] GetAllComponents<TYPE>(this GameObject gameObject) where TYPE : class | |
{ | |
gameObject = gameObject.transform.root.gameObject; | |
if (typeof(TYPE).IsInterface) | |
{ | |
List<TYPE> ret = new List<TYPE>(); | |
TYPE add; | |
foreach (var c in gameObject.GetComponentsInChildren<Component>()) | |
{ | |
add = c as TYPE; | |
if (add != null) ret.Add(add); | |
} | |
return ret.ToArray(); | |
} | |
else return gameObject.GetComponentsInChildren<TYPE>(); | |
} | |
/// <summary> | |
/// Gets first component in the component's transfrom hiearchy | |
/// </summary> | |
/// <param name="gameObject"></param> | |
/// <param name="type">Can be any interface or UnityEngine.Component</param> | |
/// <returns></returns> | |
public static TYPE GetFirstComponent<TYPE>(this GameObject gameObject) where TYPE : class | |
{ | |
gameObject = gameObject.transform.root.gameObject; | |
if (typeof(TYPE).IsInterface) | |
{ | |
foreach (var c in gameObject.GetComponentsInChildren<Component>()) | |
{ | |
if (c is TYPE) return c as TYPE; | |
} | |
return null; | |
} | |
else return gameObject.GetComponentInChildren<TYPE>(); | |
} | |
public static TYPE GetOrAddComponent<TYPE>(this GameObject gameObject) where TYPE : Component | |
{ | |
TYPE component = gameObject.GetComponent<TYPE>(); | |
if (component == null) component = gameObject.AddComponent<TYPE>(); | |
return component; | |
} | |
#endregion | |
#region Animator extensions | |
public static void SetLayerWeight(this Animator animator, string layerName, float layerWeight) | |
{ | |
for (int i = 0; i < animator.layerCount; i++) | |
{ | |
if (animator.GetLayerName(i) == layerName) | |
{ | |
animator.SetLayerWeight(i, layerWeight); | |
return; | |
} | |
} | |
} | |
public static void LerpIKPosition(this Animator animator, AvatarIKGoal goal, Vector3 value, float time) | |
{ | |
animator.SetIKPosition(goal, Vector3.Lerp(animator.GetIKPosition(goal), value, time)); | |
} | |
public static void LerpIKPositionWeight(this Animator animator, AvatarIKGoal goal, float value, float time) | |
{ | |
animator.SetIKPositionWeight(goal, Mathf.Lerp(animator.GetIKPositionWeight(goal), value, time)); | |
} | |
public static void LerpIKRotation(this Animator animator, AvatarIKGoal goal, Quaternion value, float time) | |
{ | |
animator.SetIKRotation(goal, Quaternion.Lerp(animator.GetIKRotation(goal), value, time)); | |
} | |
public static void LerpIKRotationWeight(this Animator animator, AvatarIKGoal goal, float value, float time) | |
{ | |
animator.SetIKRotationWeight(goal, Mathf.Lerp(animator.GetIKRotationWeight(goal), value, time)); | |
} | |
#endregion | |
#region Texture2D extensions | |
public static Texture2D ResizeKeepData(this Texture2D t, int width, int height) | |
{ | |
int oldW = t.width; | |
int oldH = t.height; | |
Color[] pixels = t.GetPixels(); | |
t.Resize(width, height); | |
for (int x = 0; x < t.width; x++) | |
{ | |
for (int y = 0; y < t.height; y++) | |
{ | |
var color = pixels[ | |
(x / t.width * oldW) + | |
(y / t.height * oldH) * oldW | |
]; | |
t.SetPixel(x, y, color); | |
} | |
} | |
t.Apply(); | |
return t; | |
} | |
private static Rect GetRectWidthHeight(this Texture2D text) | |
{ | |
return new Rect(0, 0, text.width, text.height); | |
} | |
public static void CopyTo(this Texture2D source, Texture2D target, Rect targetRect) | |
{ | |
source.CopyTo(target, targetRect, source.GetRectWidthHeight()); | |
} | |
public static void CopyTo(this Texture2D source, Texture2D target, Rect targetRect, Rect sourceRect) | |
{ | |
var xMin = Mathf.RoundToInt(targetRect.xMin); | |
var xMax = Mathf.RoundToInt(targetRect.xMax); | |
var yMin = Mathf.RoundToInt(targetRect.yMin); | |
var yMax = Mathf.RoundToInt(targetRect.yMax); | |
for (int x = xMin; x < xMax; x++) | |
{ | |
for (int y = yMin; y < xMax; y++) | |
{ | |
var u = sourceRect.xMin + x / xMax * sourceRect.width; | |
var v = sourceRect.yMax + y / yMax * sourceRect.height; | |
var c = source.GetPixelBilinear(u, v); | |
target.SetPixel(x, y, c); | |
} | |
} | |
} | |
#endregion | |
#region Camera extensions | |
public static Vector3 WorldToGUIPosition(this Camera cam, Vector3 worldPos) | |
{ | |
var p = cam.WorldToScreenPoint(worldPos); | |
p.y = cam.pixelHeight - p.y; | |
return p; | |
} | |
#endregion | |
#region GameObject extensions | |
public static void Destroy(this GameObject gameObject) | |
{ | |
GameObject.Destroy(gameObject); | |
} | |
#endregion | |
#region Transform extensions | |
public static void DestroyAllChildren(this Transform transform) | |
{ | |
foreach (Transform child in transform) | |
Transform.Destroy(child); | |
} | |
#endregion | |
} | |
public class CollidersState | |
{ | |
public IEnumerable<Collider> Colliders { get; private set; } | |
private struct ColliderEnabled | |
{ | |
public Collider collider; | |
public bool enabled; | |
} | |
List<ColliderEnabled> state = new List<ColliderEnabled>(); | |
public CollidersState(IEnumerable<Collider> colliders) | |
{ | |
this.Colliders = colliders; | |
SaveState(); | |
} | |
public void SaveState() | |
{ | |
state.Clear(); | |
foreach (var c in Colliders) | |
{ | |
if (c) | |
state.Add(new ColliderEnabled() | |
{ | |
collider = c, | |
enabled = c.enabled, | |
}); | |
} | |
} | |
public void RestoreState() | |
{ | |
foreach (var s in state) | |
{ | |
if (s.collider) | |
s.collider.enabled = s.enabled; | |
} | |
} | |
public void DisableAllColliders() | |
{ | |
Colliders.ForEach(c => c.enabled = false); | |
} | |
public void EnableAllColiders() | |
{ | |
Colliders.ForEach(c => c.enabled = true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment