using System; using UnityEngine; namespace GameKit.Dependencies.Utilities { public static class Floats { /// /// Used to randomize float values. /// private static System.Random _random = new(); /// /// Sets a source float to value if equal to or greater than tolerance. /// /// Float to check against tolerance. /// Tolerance float must be equal to or greater than to change to value. /// Value source is set to when breaking tolerance. public static float SetIfOverTolerance(this float source, float tolerance, float value) { if (source >= tolerance) source = value; return source; } /// /// Sets a source float to value if equal to or less than tolerance. /// /// Float to check against tolerance. /// Tolerance float must be equal to or less than to change to value. /// Value source is set to when breaking tolerance. public static float SetIfUnderTolerance(this float source, float tolerance, float value) { if (source <= tolerance) source = value; return source; } /// /// Returns how much time is left on an endTime. Returns -1 if no time is left. /// /// public static float TimeRemainingValue(this float endTime) { float remaining = endTime - Time.time; //None remaining. if (remaining < 0f) return -1f; return (endTime - Time.time); } /// /// Returns how much time is left on an endTime. Returns -1 if no time is left. /// /// public static int TimeRemainingValue(this float endTime, bool useFloor = true) { float remaining = endTime - Time.time; //None remaining. if (remaining < 0f) return -1; float result = (endTime - Time.time); return (useFloor) ? Mathf.FloorToInt(result) : Mathf.CeilToInt(result); } /// /// Returns time remaining as a string using hh:mm:ss. /// /// /// Number of places to return. 1 is seconds, 2 is minutes, 3 is hours. If a placement does not exist it is replaced with 00. /// True to return an empty string when value is 0 or less. /// public static string TimeRemainingText(this float value, byte segments, bool emptyOnZero = false) { if (emptyOnZero && value <= 0f) return string.Empty; int timeRounded = Math.Max(Mathf.RoundToInt(value), 0); TimeSpan t = TimeSpan.FromSeconds(timeRounded); int hours = Mathf.FloorToInt(t.Hours); int minutes = Mathf.FloorToInt(t.Minutes); int seconds = Mathf.FloorToInt(t.Seconds); string timeText; if (segments == 1) { seconds += (minutes * 60); seconds += (hours * 3600); timeText = string.Format("{0:D2}", seconds); } else if (segments == 2) { minutes += (hours * 60); timeText = string.Format("{0:D2}:{1:D2}", minutes, seconds); } else { timeText = string.Format("{0:D2}:{1:D2}:{2:D2}", hours, minutes, seconds); } return timeText; } /// /// Provides a random inclusive int within a given range. Preferred over Unity's Random to eliminate confusion as Unity uses inclusive for floats max, and exclusive for int max. /// /// Inclusive minimum value. /// Inclusive maximum value. /// public static float RandomInclusiveRange(float minimum, float maximum) { double min = Convert.ToDouble(minimum); double max = Convert.ToDouble(maximum); double result = (_random.NextDouble() * (max - min)) + min; return Convert.ToSingle(result); } /// /// Returns a random float between 0f and 1f. /// /// public static float Random01() { return RandomInclusiveRange(0f, 1f); } /// /// Returns if a target float is within variance of the source float. /// /// /// /// public static bool Near(this float a, float b, float tolerance = 0.01f) { return (Mathf.Abs(a - b) <= tolerance); } /// /// Clamps a float and returns if the float required clamping. /// /// /// /// /// /// public static float Clamp(float value, float min, float max, ref bool clamped) { clamped = (value < min); if (clamped) return min; clamped = (value > min); if (clamped) return max; clamped = false; return value; } /// /// Returns a float after being adjusted by the specified variance. /// /// /// /// public static float Variance(this float source, float variance) { float pickedVariance = RandomInclusiveRange(1f - variance, 1f + variance); return (source * pickedVariance); } /// /// Sets a float value to result after being adjusted by the specified variance. /// /// /// /// public static void Variance(this float source, float variance, ref float result) { float pickedVariance = RandomInclusiveRange(1f - variance, 1f + variance); result = (source * pickedVariance); } /// /// Returns negative-one, zero, or postive-one of a value instead of just negative-one or positive-one. /// /// Value to sign. /// Precise sign. public static float PreciseSign(float value) { if (value == 0f) return 0f; else return (Mathf.Sign(value)); } /// /// Returns if a float is within a range. /// /// Value of float. /// Minimum of range. /// Maximum of range. /// public static bool InRange(this float source, float rangeMin, float rangeMax) { return (source >= rangeMin && source <= rangeMax); } /// /// Randomly flips a float value. /// /// /// public static float RandomlyFlip(this float value) { if (Ints.RandomInclusiveRange(0, 1) == 0) return value; else return (value *= -1f); } } }