Skip to content

Instantly share code, notes, and snippets.

@drawcode
Created December 10, 2012 21:57
Show Gist options
  • Save drawcode/4253733 to your computer and use it in GitHub Desktop.
Save drawcode/4253733 to your computer and use it in GitHub Desktop.
Unity Utils C#
using System;
using System.Collections.Generic;
public static class ArrayUtil
{
/// <summary>
/// Filter the given array into an array of a derived type
/// </summary>
/// <returns>
/// A new array that contains only the items in src that
/// are of the given derived type U
/// </returns>
/// <param name='src'>
/// Array to filter
/// </param>
/// <typeparam name='T'>
/// The item type of the array to filter
/// </typeparam>
/// <typeparam name='U'>
/// The type, derived from T, to filter the array to
/// </typeparam>
///
public static U[] Filter<T, U>(T[] src)
where U : T
{
var res = new List<U>();
foreach(var item in src) {
if(item is U)
res.Add((U)item);
}
return res.ToArray();
}
/// <summary>
/// Filter the given array into a list of a derived type
/// </summary>
/// <returns>
/// A new list that contains only the items in src that
/// are of the given derived type U
/// </returns>
/// <param name='src'>
/// Array to filter
/// </param>
/// <typeparam name='T'>
/// The item type of the array to filter
/// </typeparam>
/// <typeparam name='U'>
/// The type, derived from T, to filter the array to
/// </typeparam>
///
public static List<U> FilterToList<T, U>(T[] src)
where U : T
{
var res = new List<U>();
foreach(var item in src) {
if(item is U)
res.Add((U)item);
}
return res;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoroutineUtil : MonoBehaviour {
private static CoroutineUtil instance;
private static CoroutineUtil Instance {
get {
if(instance == null) {
instance = ObjectUtil.FindObject<CoroutineUtil>();
if(instance == null) {
instance =
new GameObject("CoroutineUtil", typeof(CoroutineUtil))
.GetComponent<CoroutineUtil>();
}
}
return instance;
}
}
/// <summary>
/// Start the specified coroutine.
/// </summary>
/// <param name='coroutine'>
/// Coroutine.
/// </param>
///
public static YieldInstruction Start(IEnumerator coroutine) {
return Instance.StartCoroutine(coroutine);
}
/// <summary>
/// Start the specified action delegate as a coroutine.
/// </summary>
/// <param name='action'>
/// Action.
/// </param>
///
public static YieldInstruction Start(Action action) {
return Instance.StartCoroutine(RunCo(action));
}
/// <summary>
/// Start the specified action delegate as a coroutine using t.
/// </summary>
/// <param name='action'>
/// Action.
/// </param>
/// <param name='t'>
/// T.
/// </param>
/// <typeparam name='T'>
/// The 1st type parameter.
/// </typeparam>
public static YieldInstruction Start<T>(Action<T> action, T t) {
return Instance.StartCoroutine(RunCo(() => { action(t); }));
}
/// <summary>
/// Start the specified action delegate as a coroutine using t and u.
/// </summary>
/// <param name='action'>
/// Action.
/// </param>
/// <param name='t'>
/// T.
/// </param>
/// <param name='u'>
/// U.
/// </param>
/// <typeparam name='T'>
/// The 1st type parameter.
/// </typeparam>
/// <typeparam name='U'>
/// The 2nd type parameter.
/// </typeparam>
public static YieldInstruction Start<T,U>(Action<T,U> action, T t, U u) {
return Instance.StartCoroutine(RunCo(() => { action(t, u); }));
}
/// <summary>
/// Start the specified action delegate as a coroutine using t, u and v.
/// </summary>
/// <param name='action'>
/// Action.
/// </param>
/// <param name='t'>
/// T.
/// </param>
/// <param name='u'>
/// U.
/// </param>
/// <param name='v'>
/// V.
/// </param>
/// <typeparam name='T'>
/// The 1st type parameter.
/// </typeparam>
/// <typeparam name='U'>
/// The 2nd type parameter.
/// </typeparam>
/// <typeparam name='V'>
/// The 3rd type parameter.
/// </typeparam>
public static YieldInstruction Start<T,U,V>(Action<T,U,V> action, T t, U u, V v) {
return Instance.StartCoroutine(RunCo(() => { action(t, u, v); }));
}
/// <summary>
/// Start the specified action delegate as a coroutine using t, u, v and w.
/// </summary>
/// <param name='action'>
/// Action.
/// </param>
/// <param name='t'>
/// T.
/// </param>
/// <param name='u'>
/// U.
/// </param>
/// <param name='v'>
/// V.
/// </param>
/// <param name='w'>
/// W.
/// </param>
/// <typeparam name='T'>
/// The 1st type parameter.
/// </typeparam>
/// <typeparam name='U'>
/// The 2nd type parameter.
/// </typeparam>
/// <typeparam name='V'>
/// The 3rd type parameter.
/// </typeparam>
/// <typeparam name='W'>
/// The 4th type parameter.
/// </typeparam>
public static YieldInstruction Start<T,U,V,W>(Action<T,U,V,W> action, T t, U u, V v, W w) {
return Instance.StartCoroutine(RunCo(() => { action(t, u, v, w); }));
}
//Driver for Start
private static IEnumerator RunCo(Action action) {
action();
yield break;
}
public static YieldInstruction Wait(float seconds) {
return new WaitForSeconds(seconds);
}
public static YieldInstruction WaitForFixedUpdate() {
return new WaitForFixedUpdate();
}
public static YieldInstruction WaitForEndOfFrame() {
return new WaitForEndOfFrame();
}
/// <summary>
/// Wait for all the specified yield instructions to complete using
/// a wrapper coroutine.
/// </summary>
/// <param name='routines'>
/// Routines.
/// </param>
public static YieldInstruction Wait(IList<object> yields) {
return Instance.StartCoroutine(WaitCo(yields));
}
public static YieldInstruction Wait(params object[] yields) {
return Instance.StartCoroutine(WaitCo(yields));
}
//Driver for Wait
private static IEnumerator WaitCo(IEnumerable<object> yields) {
foreach(var y in yields) {
yield return y;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using UnityEngine;
public class FileSystemUtil {
#if !UNITY_WEBPLAYER
public static bool CheckFileExists(string path) {
return File.Exists(path);
}
public static void CopyFile(string dataFilePath, string persistenceFilePath) {
//Debug.Log("dataFilePath: " + dataFilePath);
//Debug.Log("persistenceFilePath: " + persistenceFilePath);
if(File.Exists(dataFilePath) && (!File.Exists(persistenceFilePath) || Application.isEditor)) {
//Debug.Log("fileCopied: " + persistenceFilePath);
// Copy file if it does not exist
File.Copy(dataFilePath, persistenceFilePath, true);
//SystemHelper.SetNoBackupFlag(persistenceFilePath);
}
}
public static void MoveFile(string dataFilePath, string persistenceFilePath) {
//Debug.Log("dataFilePath: " + dataFilePath);
//Debug.Log("persistenceFilePath: " + persistenceFilePath);
if(File.Exists(dataFilePath) && (!File.Exists(persistenceFilePath) || Application.isEditor)) {
//Debug.Log("fileMoved: " + persistenceFilePath);
File.Move(dataFilePath, persistenceFilePath);
//SystemHelper.SetNoBackupFlag(persistenceFilePath);
}
}
public static byte[] ReadAllBytes(string fileName) {
return File.ReadAllBytes(fileName);
}
public static void WriteAllBytes(string fileName, byte[] buffer) {
File.WriteAllBytes(fileName, buffer);
}
public static byte[] ReadStream(string fileName) {
byte[] buffer = null;
if(File.Exists(fileName)) {
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long length = new FileInfo(fileName).Length;
buffer = br.ReadBytes((int)length);
br.Close();
fs.Close();
}
return buffer;
}
public static void WriteStream(string fileName, byte[] data) {
StreamWriter sw = new StreamWriter(fileName, false, Encoding.ASCII);
sw.Write(data);
sw.Flush();
sw.Close();
}
public static string ReadString(string fileName) {
string contents = "";
if(File.Exists(fileName)) {
StreamReader sr = new StreamReader(fileName, true);
contents = sr.ReadToEnd();
sr.Close();
}
return contents;
}
public static void WriteString(string fileName, string data)
{
WriteString(fileName, data, false);
}
public static void WriteString(string fileName, string data, bool append)
{
StreamWriter sw = new StreamWriter(fileName, append);
sw.Write(data);
sw.Flush();
sw.Close();
}
public static void RemoveFilesLikeRecursive(DirectoryInfo dirInfo, string fileKey) {
foreach(FileInfo fileInfo in dirInfo.GetFiles()) {
if(fileInfo.FullName.Contains(fileKey)) {
File.Delete(fileInfo.FullName);
}
}
foreach(DirectoryInfo dirInfoItem in dirInfo.GetDirectories()) {
RemoveFilesLikeRecursive(dirInfoItem, fileKey);
}
}
public static void CopyFilesLikeRecursive(
DirectoryInfo dirInfoCurrent,
DirectoryInfo dirInfoFrom,
DirectoryInfo dirInfoTo,
string filter,
List<string> excludeExts) {
foreach(FileInfo fileInfo in dirInfoCurrent.GetFiles()) {
if(fileInfo.FullName.Contains(filter)) {
string fileTo = fileInfo.FullName.Replace(dirInfoFrom.FullName, dirInfoTo.FullName);
if(!CheckFileExtention(fileTo, excludeExts)) {
string directoryTo = Path.GetDirectoryName(fileTo);
if(!Directory.Exists(directoryTo)) {
Directory.CreateDirectory(directoryTo);
}
File.Copy(fileInfo.FullName, fileTo, true);
}
}
}
foreach(DirectoryInfo dirInfoItem in dirInfoCurrent.GetDirectories()) {
CopyFilesLikeRecursive(dirInfoItem, dirInfoFrom, dirInfoTo, filter, excludeExts);
}
}
public static bool CheckFileExtention(string path, List<string> extensions) {
foreach(string ext in extensions) {
if(path.ToLower().EndsWith(ext.ToLower())) {
return true;
}
}
return false;
}
public static void MoveFilesLikeRecursive(
DirectoryInfo dirInfoCurrent,
DirectoryInfo dirInfoFrom,
DirectoryInfo dirInfoTo,
string filter,
List<string> excludeExts) {
foreach(FileInfo fileInfo in dirInfoCurrent.GetFiles()) {
if(fileInfo.FullName.Contains(filter)) {
string fileTo = fileInfo.FullName.Replace(dirInfoFrom.FullName, dirInfoTo.FullName);
if(!CheckFileExtention(fileTo, excludeExts)) {
string directoryTo = Path.GetDirectoryName(fileTo);
if(!Directory.Exists(directoryTo)) {
Directory.CreateDirectory(directoryTo);
}
Debug.Log("fileTo:" + fileTo);
if(File.Exists(fileTo)) {
File.Delete(fileTo);
}
File.Move(fileInfo.FullName, fileTo);
}
}
}
foreach(DirectoryInfo dirInfoItem in dirInfoCurrent.GetDirectories()) {
MoveFilesLikeRecursive(dirInfoItem, dirInfoFrom, dirInfoTo, filter, excludeExts);
}
}
public static void RemoveDirectoriesLikeRecursive(
DirectoryInfo dirInfoCurrent,
string filterLike,
string filterNotLike) {
foreach(DirectoryInfo dirInfoItem in dirInfoCurrent.GetDirectories()) {
RemoveDirectoriesLikeRecursive(dirInfoItem, filterLike, filterNotLike);
}
if(dirInfoCurrent.FullName.Contains(filterLike)
&& !dirInfoCurrent.FullName.Contains(filterNotLike)) {
Directory.Delete(dirInfoCurrent.FullName, true);
}
}
#endif
}
using System;
using System.Collections;
using System.Collections.Generic;
public class FormatUtil
{
public static string GetFormattedTime(double seconds, string format) {
TimeSpan t = TimeSpan.FromSeconds(seconds);
string formatted = string.Format(format,
t.Hours,
t.Minutes,
t.Seconds,
t.Milliseconds);
return formatted;
}
public static string GetFormattedTimeMinutesSecondsMsSmall(double seconds) {
return GetFormattedTime(seconds, "{1:D2}:{2:D2}.{3:D1}");
}
public static string GetFormattedTimeMinutesSecondsMs(double seconds) {
return GetFormattedTime(seconds, "{1:D2}:{2:D2}.{3:D3}");
}
public static string GetFormattedTimeHoursMinutesSecondsMsSmall(double seconds) {
return GetFormattedTime(seconds, "{0:D2}:{1:D2}:{2:D2}.{3:D1}");
}
public static string GetFormattedTimeHoursMinutesSecondsMs(double seconds) {
return GetFormattedTime(seconds, "{0:D2}:{1:D2}:{2:D2}.{3:D3}");
}
public static string GetStringTrimmedExact(string longString, int descriptionTextRowLength) {
if(longString.Length > descriptionTextRowLength) {
longString = longString.Substring(0, descriptionTextRowLength);
longString += "...";
}
return longString;
}
public static string GetStringTrimmed(string longString, int descriptionTextRowLength) {
string filtered = longString;
if(!string.IsNullOrEmpty(filtered)) {
List<string> lines = FormatUtil.SplitStringAcrossLines(longString, descriptionTextRowLength);
if(lines.Count > 0) {
filtered = lines[0];
if(filtered.Length > descriptionTextRowLength) {
filtered += "...";
}
}
}
return filtered;
}
public static string GetStringTrimmedWithBreaks(string longString, int lineLength) {
string trimmedString = "";
if(!string.IsNullOrEmpty(longString)) {
List<string> lines = FormatUtil.SplitStringAcrossLines(longString, lineLength);
foreach(string s in lines) {
trimmedString += s + "\n";
}
}
return trimmedString;
}
public static List<string> SplitStringAcrossLines(string fullString, int maxStringLength) {
List<string> lines = new List<string>();
string[] words = fullString.Split(' ');
int currentLength = 0;
int currentMaxLength = maxStringLength;
string currentLine = "";
foreach(string word in words) {
currentLength += word.Length + 1;
if(currentLength >= currentMaxLength) {
// start next line
lines.Add(currentLine);
currentLine = "";
currentLength = word.Length + 1;
}
currentLine += word + " ";
}
if(!string.IsNullOrEmpty(currentLine)) {
lines.Add(currentLine);
}
return lines;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
public class MathUtil {
public static float Hermite(float start, float end, float value) {
return Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value));
}
public static float Sinerp(float start, float end, float value) {
return Mathf.Lerp(start, end, Mathf.Sin(value * Mathf.PI * 0.5f));
}
public static float Coserp(float start, float end, float value) {
return Mathf.Lerp(start, end, 1.0f - Mathf.Cos(value * Mathf.PI * 0.5f));
}
public static float Berp(float start, float end, float value) {
value = Mathf.Clamp01(value);
value = (Mathf.Sin(value * Mathf.PI * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + (1.2f * (1f - value)));
return start + (end - start) * value;
}
public static float SmoothStep(float x, float min, float max) {
x = Mathf.Clamp(x, min, max);
float v1 = (x - min) / (max - min);
float v2 = (x - min) / (max - min);
return -2 * v1 * v1 * v1 + 3 * v2 * v2;
}
public static float Lerp(float start, float end, float value) {
return ((1.0f - value) * start) + (value * end);
}
public static Vector3 NearestPoint(Vector3 lineStart, Vector3 lineEnd, Vector3 point) {
Vector3 lineDirection = Vector3.Normalize(lineEnd - lineStart);
float closestPoint = Vector3.Dot((point - lineStart), lineDirection) / Vector3.Dot(lineDirection, lineDirection);
return lineStart + (closestPoint * lineDirection);
}
public static Vector3 NearestPointStrict(Vector3 lineStart, Vector3 lineEnd, Vector3 point) {
Vector3 fullDirection = lineEnd - lineStart;
Vector3 lineDirection = Vector3.Normalize(fullDirection);
float closestPoint = Vector3.Dot((point - lineStart), lineDirection) / Vector3.Dot(lineDirection, lineDirection);
return lineStart + (Mathf.Clamp(closestPoint, 0.0f, Vector3.Magnitude(fullDirection)) * lineDirection);
}
public static float Bounce(float x) {
return Mathf.Abs(Mathf.Sin(6.28f * (x + 1f) * (x + 1f)) * (1f - x));
}
// test for value that is near specified float (due to floating point inprecision)
// all thanks to Opless for this!
public static bool Approx(float val, float about, float range) {
return ((Mathf.Abs(val - about) < range));
}
// test if a Vector3 is close to another Vector3 (due to floating point inprecision)
// compares the square of the distance to the square of the range as this
// avoids calculating a square root which is much slower than squaring the range
public static bool Approx(Vector3 val, Vector3 about, float range) {
return ((val - about).sqrMagnitude < range * range);
}
/*
* CLerp - Circular Lerp - is like lerp but handles the wraparound from 0 to 360.
* This is useful when interpolating eulerAngles and the object
* crosses the 0/360 boundary. The standard Lerp function causes the object
* to rotate in the wrong direction and looks stupid. Clerp fixes that.
*/
public static float Clerp(float start, float end, float value) {
float min = 0.0f;
float max = 360.0f;
float half = Mathf.Abs((max - min) / 2.0f);//half the distance between min and max
float retval = 0.0f;
float diff = 0.0f;
if((end - start) < -half) {
diff = ((max - start) + end) * value;
retval = start + diff;
}
else if((end - start) > half) {
diff = -((max - end) + start) * value;
retval = start + diff;
}
else
retval = start + (end - start) * value;
// Debug.Log("Start: " + start + " End: " + end + " Value: " + value + " Half: " + half + " Diff: " + diff + " Retval: " + retval);
return retval;
}
public static int Modulo(int x, int m) {
m = Mathf.Abs(m);
return (x % m + m) % m;
}
public static Vector2 Circle(float angle, float radius) {
return new Vector2(radius * Mathf.Cos(angle),
radius * -Mathf.Sin(angle));
}
public static float Hypotenuse(float a, float b) {
return MathUtil.SquareRoot(HypotenuseSquared(a, b));
}
public static float HypotenuseSquared(float a, float b) {
return MathUtil.Square(a) + MathUtil.Square(b);
}
public static float SquareRoot(float val) {
return Mathf.Sqrt(val);
}
public static float Square(float val) {
return val * val;
}
public static float SquareSign(float val) {
return Square(val) * Mathf.Sign(val);
}
public static float Cube(float val) {
return val * val * val;
}
public static int Clamp(int val, int min, int max) {
return Math.Max(Math.Min(val, max), min);
}
public static float MirrorUnitClamp(float val) {
return Mathf.Clamp(val, -1, 1);
}
public static float UnitClamp(float val) {
return Mathf.Clamp(val, 0f, 1f);
}
public static float MPSToMPH(float metersPerSecond) {
return metersPerSecond * 2.23693629f;
}
public static float MPHToMPS(float milesPerHour) {
return milesPerHour * 0.44704f;
}
public static float KMHToMPH(float kilometersPerHour) {
return kilometersPerHour / 1.609f;
}
public static float RPMToAV(float rpm) {
return rpm * ((2f * Mathf.PI) / 60f);
}
public static float AVToRPM(float angularVelocity) {
return angularVelocity * (60f / (2f * Mathf.PI));
}
public static float NormalizeAngleHalf(float angle) {
angle = NormalizeAngle(angle);
if(angle > 180f)
return -(360f-angle);
return angle;
}
public static float NormalizeAngle(float angle) {
return ((angle % 360f) + 360f) % 360f;
}
public static float ClampAngle(float a, float min, float max) {
while (max < min)
max += 360f;
while (a > max)
a -= 360f;
while (a < min)
a += 360f;
if (a > max) {
if (a - (max + min) * 0.5f < 180f)
return max;
else
return min;
}
else
return a;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment