Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save LongChau/fa2ce8b46a57af45d09bff943de68c5c to your computer and use it in GitHub Desktop.
Save LongChau/fa2ce8b46a57af45d09bff943de68c5c to your computer and use it in GitHub Desktop.
Some useful extension method for Unity3D
A collection of useful C# extension methods for the Unity engine.
using System;
using System.Collections;
using System.Collections.Generic;
public static class ShuffleListExtensions
{
/// <summary>
/// Shuffle the list in place using the Fisher-Yates method.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
public static void Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
/// <summary>
/// Return a random item from the list.
/// Sampling with replacement.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static T RandomItem<T>(this IList<T> list)
{
if (list.Count == 0) throw new System.IndexOutOfRangeException("Cannot select a random item from an empty list");
return list[UnityEngine.Random.Range(0, list.Count)];
}
/// <summary>
/// Removes a random item from the list, returning that item.
/// Sampling without replacement.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static T RemoveRandom<T>(this IList<T> list)
{
if (list.Count == 0) throw new System.IndexOutOfRangeException("Cannot remove a random item from an empty list");
int index = UnityEngine.Random.Range(0, list.Count);
T item = list[index];
list.RemoveAt(index);
return item;
}
}
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
public static class StringExtensionMethods
{
public static string Truncate(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
// Named format strings from object attributes. Eg:
// string blaStr = aPerson.ToString("My name is {FirstName} {LastName}.")
// From: http://www.hanselman.com/blog/CommentView.aspx?guid=fde45b51-9d12-46fd-b877-da6172fe1791
public static string ToString(this object anObject, string aFormat)
{
return ToString(anObject, aFormat, null);
}
public static string ToString(this object anObject, string aFormat, IFormatProvider formatProvider)
{
StringBuilder sb = new StringBuilder();
Type type = anObject.GetType();
Regex reg = new Regex(@"({)([^}]+)(})", RegexOptions.IgnoreCase);
MatchCollection mc = reg.Matches(aFormat);
int startIndex = 0;
foreach (Match m in mc)
{
Group g = m.Groups[2]; //it's second in the match between { and }
int length = g.Index - startIndex - 1;
sb.Append(aFormat.Substring(startIndex, length));
string toGet = string.Empty;
string toFormat = string.Empty;
int formatIndex = g.Value.IndexOf(":"); //formatting would be to the right of a :
if (formatIndex == -1) //no formatting, no worries
{
toGet = g.Value;
}
else //pickup the formatting
{
toGet = g.Value.Substring(0, formatIndex);
toFormat = g.Value.Substring(formatIndex + 1);
}
//first try properties
PropertyInfo retrievedProperty = type.GetProperty(toGet);
Type retrievedType = null;
object retrievedObject = null;
if (retrievedProperty != null)
{
retrievedType = retrievedProperty.PropertyType;
retrievedObject = retrievedProperty.GetValue(anObject, null);
}
else //try fields
{
FieldInfo retrievedField = type.GetField(toGet);
if (retrievedField != null)
{
retrievedType = retrievedField.FieldType;
retrievedObject = retrievedField.GetValue(anObject);
}
}
if (retrievedType != null) //Cool, we found something
{
string result = string.Empty;
if (toFormat == string.Empty) //no format info
{
result = retrievedType.InvokeMember("ToString",
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase
, null, retrievedObject, null) as string;
}
else //format info
{
result = retrievedType.InvokeMember("ToString",
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase
, null, retrievedObject, new object[] { toFormat, formatProvider }) as string;
}
sb.Append(result);
}
else //didn't find a property with that name, so be gracious and put it back
{
sb.Append("{");
sb.Append(g.Value);
sb.Append("}");
}
startIndex = g.Index + g.Length + 1;
}
if (startIndex < aFormat.Length) //include the rest (end) of the string
{
sb.Append(aFormat.Substring(startIndex));
}
return sb.ToString();
}
}
using UnityEngine;
public static class ExtensionMethods
{
public static float LinearRemap(this float value,
float valueRangeMin, float valueRangeMax,
float newRangeMin, float newRangeMax)
{
return (value - valueRangeMin) / (valueRangeMax - valueRangeMin) * (newRangeMax - newRangeMin) + newRangeMin;
}
public static int WithRandomSign(this int value, float negativeProbability = 0.5f)
{
return Random.value < negativeProbability ? -value : value;
}
}
using UnityEngine;
public static class VectorExtensionMethods {
public static Vector2 xy(this Vector3 v) {
return new Vector2(v.x, v.y);
}
public static Vector3 WithX(this Vector3 v, float x) {
return new Vector3(x, v.y, v.z);
}
public static Vector3 WithY(this Vector3 v, float y) {
return new Vector3(v.x, y, v.z);
}
public static Vector3 WithZ(this Vector3 v, float z) {
return new Vector3(v.x, v.y, z);
}
public static Vector2 WithX(this Vector2 v, float x) {
return new Vector2(x, v.y);
}
public static Vector2 WithY(this Vector2 v, float y) {
return new Vector2(v.x, y);
}
public static Vector3 WithZ(this Vector2 v, float z) {
return new Vector3(v.x, v.y, z);
}
// axisDirection - unit vector in direction of an axis (eg, defines a line that passes through zero)
// point - the point to find nearest on line for
public static Vector3 NearestPointOnAxis(this Vector3 axisDirection, Vector3 point, bool isNormalized = false)
{
if (!isNormalized) axisDirection.Normalize();
var d = Vector3.Dot(point, axisDirection);
return axisDirection * d;
}
// lineDirection - unit vector in direction of line
// pointOnLine - a point on the line (allowing us to define an actual line in space)
// point - the point to find nearest on line for
public static Vector3 NearestPointOnLine(
this Vector3 lineDirection, Vector3 point, Vector3 pointOnLine, bool isNormalized = false)
{
if (!isNormalized) lineDirection.Normalize();
var d = Vector3.Dot(point - pointOnLine, lineDirection);
return pointOnLine + (lineDirection * d);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment