Skip to content

Instantly share code, notes, and snippets.

@Marsgames
Last active October 26, 2023 08:47
Show Gist options
  • Save Marsgames/a26186ab3e579f770f441a109b097f0a to your computer and use it in GitHub Desktop.
Save Marsgames/a26186ab3e579f770f441a109b097f0a to your computer and use it in GitHub Desktop.
Some useful functions snippet for Unity

Useful Unity snippets

A simple lerp from x value to y value in z seconds.

A function that allow a 2D GameObject to look at another GameObject, rotating only around Z axis.

A class (only 1 function is really important) that allow you to move a GameObject describing a simple Bezier curve (Only one tangent point).
Using gizmos to show the path that will be use by the object.

Get the point representing the projection position of an object. I use this function to have ui lifebars always be perpendicular with camera plan

This class allows us to create a "constant" at runtime. You can pass any value, and you will not be able to update it after its creation.
You can directly pass the variable into a string (without using its Value parameter) to use it as a string.
You can directly pass the variable into another one (without using its Value parameter) to use it a its T value.

RuntimeConst<int> age = new RuntimeConst<int>(28);
Console.WriteLine ("My age is {age}"); // My age is 28

int raphaelAge = age;
Console.WriteLine(raphaelAge > 18); // True
/// <summary>
/// Lerp from X to Y in Z seconds
/// </summary>
/// <param name="from">start value of the gauge [0,1]</param>
/// <param name="to">End value of the gauge [0,1]</param>
/// <param name="interpolationTime">How long does it take to interpolate from start value to end value</param>
/// <returns></returns>
private IEnumerator Lerp(float from, float to, int interpolationTime = 3)
{
if (from.Equals(to))
{
yield break;
}
float elapsedTime = 0f;
float currentAmount;
while (elapsedTime < interpolationTime)
{
elapsedTime += Time.deltaTime;
currentAmount = Mathf.Lerp(from, to, elapsedTime / interpolationTime);
// Do whatever you want with the value of currenAmount
yield return null;
}
}
///////////////////////////////////////////////////////////////////////
/// <summary>
/// Linearly interpolate between a and b by t
/// </summary>
/// <param name="a">Start value</param>
/// <param name="b">End value</param>
/// <param name="t">0 == a | 1 == b</param>
/// <returns></returns>
public static float Lerp(float from, float to, float t)
{
return from * (1 - t) + to * t;
}
/// <summary>
/// Calculate the linear parameter t that produce the interpolant value within the range [a,b]
/// </summary>
/// <param name="a">Start value</param>
/// <param name="b">End value</param>
/// <param name="value">Value between a and b, to get how much percent it is</param>
/// <returns></returns>
public static float InverseLerp(float from, float to, float value)
{
return (value - from) / (to - from);
}
/// <summary>
/// This function allow a 2D object to look at another GameObject rotating only around Z axis
///
/// <para>If you want to look at mouse use Camera.main.ScreenToWorldPoint(Input.mousePosition) as targetPosition</para>
/// </summary>
/// <param name="targetPosition">Position where you want to look at</param>
private void LookAtTarget2D(Vector3 targetPosition)
{
// Set the z position of target the same as our object
Vector3 target = targetPosition;
target.z = transform.position.z;
// Get angle between our object and the target in Radian and Degrees
float rad = Mathf.Acos(Vector3.Dot(Vector2.up, (target - transform.position).normalized));
float deg = (180 / Mathf.PI) * rad;
// Check if we want to rotate left or right
int signed = target.x > transform.position.x ? -1 : 1;
// Rotate object
transform.localEulerAngles = new Vector3(0, 0, deg * signed);
}
#region Author
/////////////////////////////////////////
// RAPHAËL DAUMAS --> MoveAlongCurve
// https://raphdaumas.wixsite.com/portfolio
// https://github.com/Marsgames
/////////////////////////////////////////
#endregion
using System.Collections;
using UnityEngine;
public class MoveAlongCurve : MonoBehaviour
{
#region Variables
[SerializeField] private Transform startPosition = null;
[SerializeField] private Transform endPosition = null;
[SerializeField] private Transform[] paths = null;
#if UNITY_EDITOR
[SerializeField] private Texture2D pathTexture = null;
[SerializeField] private bool alwaysShowPath = false;
#endif
#endregion Variables
///////////////////////////////////////////////////////////
#region Unity's functions
// Start is called before the first frame update
private void Start()
{
CheckIfSetUp();
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
if (alwaysShowPath)
{
return;
}
Color color = Color.blue;
foreach (Transform path in paths)
{
UnityEditor.Handles.DrawBezier(startPosition.position, endPosition.position, path.position, path.position, color, pathTexture, 2);
}
}
private void OnDrawGizmos()
{
if (!alwaysShowPath)
{
return;
}
Color color = Color.blue;
foreach (Transform path in paths)
{
UnityEditor.Handles.DrawBezier(startPosition.position, endPosition.position, path.position, path.position, color, pathTexture, 2);
}
}
#endif
#endregion Unity's functions
///////////////////////////////////////////////////////////
#region Functions
/// <summary>
/// Move an object while discribing a Bezier curve
/// </summary>
/// <param name="objectToMove">The GameObject you want to move</param>
/// <param name="startPoint">Start point of the Bezier curve</param>
/// <param name="tangentPoint">Tangent point of the Bezier curve</param>
/// <param name="endPoint">End point of the Bezier curve</param>
/// <param name="interpolationTimer">How long does it takes to go from start point to end point (in seconds)</param>
public void MoveObject(GameObject objectToMove, Vector3 startPoint, Vector3 tangentPoint, Vector3 endPoint, float interpolationTimer)
{
StartCoroutine(MoveObjectAlongCurve(objectToMove, startPoint, tangentPoint, endPoint, interpolationTimer));
}
/// <summary>
/// Move an object while discribing a Bezier curve
/// </summary>
/// <param name="objToMove">The GameObject you want to move</param>
/// <param name="startPoint">Start point of the Bezier curve</param>
/// <param name="tangentPoint">Tangent point of the Bezier curve</param>
/// <param name="endPoint">End point of the Bezier curve</param>
/// <param name="interpolationTimer">How long does it takes to go from start point to end point (in seconds)</param>
private IEnumerator MoveObjectAlongCurve(GameObject objToMove, Vector3 startPoint, Vector3 tangentPoint, Vector3 endPoint, float interpolationTimer)
{
float elapsedTime = 0;
objToMove.transform.position = startPosition.position;
while (elapsedTime < interpolationTimer)
{
elapsedTime += Time.deltaTime;
float t = Mathf.InverseLerp(0, interpolationTimer, elapsedTime);
objToMove.transform.position = GetPointAlongCurve(startPoint, tangentPoint, endPoint, t);
elapsedTime += Time.deltaTime;
yield return null;
}
}
/// <summary>
/// Get a point on a Bezier cruve
/// </summary>
/// <param name="startPoint">Start point of the Bezier curve</param>
/// <param name="tangentPoint">Tangent point oof the Bezier curve</param>
/// <param name="endPoint">End point of the Bezier curve</param>
/// <param name="t">Position on the curve in percentage [0,1]</param>
/// <returns></returns>
private Vector3 GetPointAlongCurve(Vector3 startPoint, Vector3 tangentPoint, Vector3 endPoint, float t)
{
return Vector3.Lerp(Vector3.Lerp(startPoint, tangentPoint, t), Vector3.Lerp(tangentPoint, endPoint, t), t);
}
#endregion Functions
///////////////////////////////////////////////////////////
#region Accessors
#endregion Accessors
///////////////////////////////////////////////////////////
#region Utils
/// <summary>
/// Checks if all variables are set up correctly, otherwise close Editor
/// </summary>
private void CheckIfSetUp()
{
#if UNITY_EDITOR
bool isSetUp = true;
if (!startPosition)
{
Debug.LogError("<b>Start Position</b> cannot be null in <color=#0000FF>" + name + "</color>", gameObject);
isSetUp = false;
}
if (!endPosition)
{
Debug.LogError("<b>End Position</b> cannot be null in <color=#0000FF>" + name + "</color>", gameObject);
isSetUp = false;
}
if (null == paths)
{
Debug.LogError("<b>Paths</b> cannot be null in <color=#0000FF>" + name + "</color>", gameObject);
isSetUp = false;
}
UnityEditor.EditorApplication.isPlaying = isSetUp;
#endif
}
#endregion Utils
}
/// <summary>
/// Get a perpendiculary projection of a point on the plan of a forward vector
/// </summary>
/// <param name="forward">Forward vector of the object to face (camera).</param>
/// <param name="objectPosition">Position of the object you want to rotate</param>
/// <returns>Point on the plan of the object to face where your object has to transform.LookAt()</returns>
private Vector3 GetPointProjection(Vector3 forward, Vector3 objectPosition)
{
float k = (-forward.x * objectPosition.x - forward.y * objectPosition.y - forward.z * objectPosition.z) / (forward.x * forward.x + forward.y * forward.y + forward.z * forward.z);
return new Vector3(k * forward.x + objectPosition.x, k * forward.y + objectPosition.y, k * forward.z + objectPosition.z);
}
public class RuntimeConst<T>
{
public T Value { get; }
public RuntimeConst(T value)
{
Value = value;
}
public override string ToString()
{
return Value.ToString(); // Utilisez la valeur stockée dans Value
}
public static implicit operator T(RuntimeConst<T> runtimeConst)
{
return runtimeConst.Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment