Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 2ba1c94b88
commit ee9aee0a1b
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e29594db72aca3c4e8422ebafb3d272d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace Febucci.Attributes
{
public class CharsDisplayTimeAttribute : PropertyAttribute
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17a442d7a8bcb7843a7b81ae4b6fcbaa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using UnityEngine;
namespace Febucci.Attributes
{
public class MinValueAttribute : PropertyAttribute
{
public float min = 0;
public MinValueAttribute(float min)
{
this.min = min;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15c1cd35897ccae4ea16b7d7bd05c74b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
using UnityEngine;
namespace Febucci.Attributes
{
public class NotZeroAttribute : PropertyAttribute
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 330d54a9b2a8cde41a7128d6f9418661
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
using UnityEngine;
namespace Febucci.Attributes
{
public class PositiveValueAttribute : PropertyAttribute
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f12d9869f06b66498d39516b6e88aa7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using System.Collections.Generic;
namespace Febucci.UI.Core
{
/// <summary>
/// Helper class. Contains methods to parse attributes/values from strings.
/// </summary>
public static class FormatUtils
{
/// <summary>
/// Tries to parse a rich text tag parameter.
/// </summary>
/// <remarks>
/// Mostly used in combination with custom typewriter actions. (Manual: <see href="https://www.febucci.com/text-animator-unity/docs/writing-custom-actions-c-sharp/">Writing Custom actions C#</see>)
/// </remarks>
/// <param name="attributes">list of all the attributesi in the rich text tag</param>
/// <param name="index">the parameter's index in the list</param>
/// <param name="defValue">default value, assigned if the parsing is not successful</param>
/// <param name="result">result from the parsing</param>
/// <returns><c>true</c> if successful</returns>
public static bool TryGetFloat(List<string> attributes, int index, float defValue, out float result)
{
if (index >= attributes.Count || index < 0)
{
result = defValue;
return false;
}
return TryGetFloat(attributes[index], defValue, out result);
}
//TODO Docs
public static bool TryGetFloat(string attribute, float defValue, out float result)
{
if (ParseFloat(attribute, out result))
return true;
result = defValue;
return false;
}
/// <summary>
/// Tries parsing a float given a string, independently of the system's culture
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
public static bool ParseFloat(string value, out float result)
{
return float.TryParse(value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out result);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa97b1b4f8a3bfa4b82ca06b835b4bb7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
namespace Febucci.UI.Core
{
internal static class TAnimExtensions
{
internal static int GetIndexOfEffectNamed<T>(this List<T> effects, string tag) where T : EffectsBase
{
for (int a = effects.Count-1; a >=0; a--) //closes the last recurring region, leaving eventual fallback/default effects unaltered
{
if (!effects[a].regionManager.IsLastRegionClosed())
{
if (effects[a].effectTag.Equals(tag))
return a;
}
}
return -1;
}
internal static bool CloseElement<T>(this List<T> effects, int listIndex, int realTextIndex) where T : EffectsBase
{
if (listIndex < 0 || listIndex >= effects.Count || effects[listIndex].regionManager.IsLastRegionClosed())
return false;
effects[listIndex].regionManager.CloseEffect(realTextIndex);
return true;
}
internal static bool CloseRegionNamed<T>(this List<T> effects, string endTag, int realTextIndex) where T : EffectsBase
{
return effects.CloseElement(effects.GetIndexOfEffectNamed(endTag), realTextIndex);
}
internal static bool TryAddingNewRegion<T>(this List<T> effects, T region) where T : EffectsBase
{
for (int a = 0; a < effects.Count; a++)
{
//Doesn't do anything if we have a similar tag open
//Since there's no need to open a new one
if (!effects[a].regionManager.IsLastRegionClosed()
&& effects[a].regionManager.entireRichTextTag.Equals(region.regionManager.entireRichTextTag))
{
return false;
}
}
//no tag open with that rich text combination - creates a new one
effects.Add(region);
return true;
}
internal static bool CloseSingleOrAllEffects<T>(this List<T> effects, string closureTag, int realTextIndex) where T : EffectsBase
{
bool atLeastOneClosed = false;
//Closes all the regions
if (closureTag.Length <= 1) //tag is <> or </> ({} or {/})
{
//Closes ALL the region opened until now
for (int k = 0; k < effects.Count; k++)
{
if (effects.CloseElement(k, realTextIndex))
{
atLeastOneClosed = true;
}
}
}
//Closes the current region
else
{
atLeastOneClosed = effects.CloseRegionNamed(closureTag, realTextIndex);
}
return atLeastOneClosed;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 769b4c3767ca8e2489e276d0e8faf913
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
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
internal const int fakeRandomsCount = 25; //18° angle difference
internal static Vector3[] 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;
}
public static bool IsTagLongEnough(string tag)
{
return tag.Length >= 3;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 792ffbd6b25610f48800fce737481b10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
using UnityEngine;
namespace Febucci.UI.Core
{
//TODO Docs
/// <summary>
/// Helper class used to interpolate effects.
/// </summary>
public static class Tween
{
public static float EaseIn(float t)
{
return t * t;
}
public static float Flip(float x)
{
return 1 - x;
}
public static float Square(float t)
{
return t * t;
}
public static float EaseOut(float t)
{
return Flip(Square(Flip(t)));
}
public static float EaseInOut(float t)
{
return Mathf.Lerp(EaseIn(t), EaseOut(t), t);
}
#region BounceOut
public static float BounceOut(float t)
{
/*
License of the original method/algorithm, modified later for C#.
------------------------Start------------------------
The MIT License
Copyright (c) 2010-2012 Tween.js authors.
Easing equations Copyright (c) 2001 Robert Penner http:/robertpenner.com/ easing/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
------------------------End------------------------
*/
if (t < (1f / 2.75f))
{
return 7.5625f * t * t;
}
else if (t < (2f / 2.75f))
{
return 7.5625f * (t -= (1.5f / 2.75f)) * t + 0.75f;
}
else if (t < (2.5f / 2.75f))
{
return 7.5625f * (t -= (2.25f / 2.75f)) * t + 0.9375f;
}
else
{
return 7.5625f * (t -= (2.625f / 2.75f)) * t + 0.984375f;
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2edcfb3709f1187429d9fda2e36df38e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: