MayHeCome/Assets/Plugins/Febucci/Text Animator/Scripts/Runtime/Utilities/TextUtilities.cs
2024-12-18 17:55:34 +08:00

216 lines
7.0 KiB
C#

using UnityEngine;
namespace Febucci.UI.Core
{
/// <summary>
/// Helper class. Contains methods (including extensions) that modify your letters positions and colors.
/// </summary>
public static class TextUtilities
{
#region Consts
/// <summary>
/// Represents the number of vertices per character/letter.
/// </summary>
/// <remarks>
/// P.S. bars/underlines have a different vertices number, but are not animated by TextAnimator.
/// </remarks>
public const int verticesPerChar = 4;
#endregion
#region Vector Utilities
public const int fakeRandomsCount = 25; //18° angle difference
internal static Vector3[] fakeRandoms;
public static Vector3[] FakeRandoms => fakeRandoms;
static bool initialized = false;
internal static void Initialize()
{
if (initialized)
return;
initialized = true;
//Creates fake randoms from a list of directions (with an incremental angle of 360/fakeRandomsCount between each)
//and then sorts them randomly, avoiding repetitions (which could have occurred using Random.insideUnitCircle)
System.Collections.Generic.List<Vector3> randomDirections = new System.Collections.Generic.List<Vector3>();
float angle;
for (float i = 0; i < 360; i += 360 / fakeRandomsCount)
{
angle = i * Mathf.Deg2Rad;
randomDirections.Add(new Vector3(Mathf.Sin(angle), Mathf.Cos(angle)).normalized);
}
fakeRandoms = new Vector3[fakeRandomsCount];
int randomIndex;
for (int i = 0; i < fakeRandoms.Length; i++)
{
randomIndex = Random.Range(0, randomDirections.Count);
fakeRandoms[i] = randomDirections[randomIndex];
randomDirections.RemoveAt(randomIndex);
}
}
/// <summary>
/// Rotates a point around a 2D center by X degrees
/// </summary>
/// <param name="vec">point to rotate</param>
/// <param name="center">rotation's center</param>
/// <param name="rotDegrees">rotation degrees</param>
/// <returns></returns>
/// <example>
/// letterVertex.RotateAround(letterMiddlePoint, angle);
/// </example>
public static Vector3 RotateAround(this Vector3 vec, Vector2 center, float rotDegrees)
{
rotDegrees *= Mathf.Deg2Rad;
float tempX = vec.x - center.x;
float tempY = vec.y - center.y;
float rotatedX = tempX * Mathf.Cos(rotDegrees) - tempY * Mathf.Sin(rotDegrees);
float rotatedY = tempX * Mathf.Sin(rotDegrees) + tempY * Mathf.Cos(rotDegrees);
vec.x = rotatedX + center.x;
vec.y = rotatedY + center.y;
return vec;
}
#endregion
/// <summary>
/// Moves a char towards a direction. Equivalent to adding a vector to all the vertices.
/// </summary>
/// <param name="vec"></param>
/// <param name="dir"></param>
/// <returns></returns>
public static void MoveChar(this Vector3[] vec, Vector3 dir)
{
for (byte j = 0; j < vec.Length; j++)
{
vec[j] += dir;
}
}
/// <summary>
/// Sets all the vertices of character to the given position.
/// </summary>
/// <param name="vec"></param>
/// <param name="pos"></param>
/// <returns></returns>
public static void SetChar(this Vector3[] vec, Vector3 pos)
{
for (byte j = 0; j < vec.Length; j++)
{
vec[j] = pos;
}
}
/// <summary>
/// Lerps all the character's vertices (without checking if pct is between 0 and 1)
/// </summary>
/// <param name="vec"></param>
/// <param name="target"></param>
/// <param name="pct"></param>
/// <returns></returns>
public static void LerpUnclamped(this Vector3[] vec, Vector3 target, float pct)
{
for (byte j = 0; j < vec.Length; j++)
{
vec[j] = Vector3.LerpUnclamped(vec[j], target, pct);
}
}
/// <summary>
/// Returns the middle position of the given array
/// </summary>
/// <param name="vec"></param>
/// <returns></returns>
public static Vector3 GetMiddlePos(this Vector3[] vec)
{
return (vec[0] + vec[2]) / 2f; //bot left and top right
//'Normal way', for arrays with any size (not happening, since Bars aren't animated)
/*
Vector3 middlePos = Vector3.zero;
for (byte j = 0; j < vec.Length; j++)
{
middlePos += vec[j];
}
return (middlePos / vec.Length);
*/
}
/// <summary>
/// Rotates all the vertices towards an angle, with their center as the rotation pivot
/// </summary>
/// <param name="vec"></param>
/// <param name="angle"></param>
/// <returns></returns>
public static void RotateChar(this Vector3[] vec, float angle)
{
Vector3 middlePos = vec.GetMiddlePos();
for (byte j = 0; j < vec.Length; j++)
{
vec[j] = vec[j].RotateAround(middlePos, angle);
}
}
public static void RotateChar(this Vector3[] vec, float angle, Vector3 pivot)
{
for (byte j = 0; j < vec.Length; j++)
{
vec[j] = vec[j].RotateAround(pivot, angle);
}
}
/// <summary>
/// Sets the color of all the vertices of the character.
/// </summary>
/// <param name="col"></param>
/// <param name="target"></param>
/// <returns></returns>
public static void SetColor(this Color32[] col, Color32 target)
{
for (byte j = 0; j < col.Length; j++)
{
col[j] = target;
}
}
/// <summary>
/// Lerps all the colors of the characters towards a given target
/// </summary>
/// <param name="col"></param>
/// <param name="target"></param>
/// <param name="pct"></param>
/// <returns></returns>
public static void LerpUnclamped(this Color32[] col, Color32 target, float pct)
{
for (byte j = 0; j < col.Length; j++)
{
col[j] = Color32.LerpUnclamped(col[j], target, pct);
}
}
/// <summary>
/// Calculates the animation curve duration
/// </summary>
/// <param name="curve"></param>
/// <returns></returns>
public static float CalculateCurveDuration(this AnimationCurve curve)
{
if (curve.keys.Length > 0)
return curve.keys[curve.length - 1].time;
return 0;
}
}
}