// ╔════════════════════════════════════════════════════════════════╗ // ║ Copyright © 2025 NWH Coding d.o.o. All rights reserved. ║ // ║ Licensed under Unity Asset Store Terms of Service: ║ // ║ https://unity.com/legal/as-terms ║ // ║ Use permitted only in compliance with the License. ║ // ║ Distributed "AS IS", without warranty of any kind. ║ // ╚════════════════════════════════════════════════════════════════╝ #region using UnityEngine; #endregion namespace NWH.Common.Utility { /// /// Extension methods for AnimationCurve manipulation and processing. /// public static class AnimationCurveExtensions { /// /// Smooths out a scripting-generated AnimationCurve by calculating appropriate tangents. /// Creates smooth transitions between keyframes. /// /// The curve to smooth. /// A new smoothed AnimationCurve. public static AnimationCurve MakeSmooth(this AnimationCurve inCurve) { AnimationCurve outCurve = new(); for (int i = 0; i < inCurve.keys.Length; i++) { float inTangent = 0; float outTangent = 0; bool intangentSet = false; bool outtangentSet = false; Vector2 point1; Vector2 point2; Vector2 deltapoint; Keyframe key = inCurve[i]; if (i == 0) { inTangent = 0; intangentSet = true; } if (i == inCurve.keys.Length - 1) { outTangent = 0; outtangentSet = true; } if (!intangentSet) { point1.x = inCurve.keys[i - 1].time; point1.y = inCurve.keys[i - 1].value; point2.x = inCurve.keys[i].time; point2.y = inCurve.keys[i].value; deltapoint = point2 - point1; inTangent = deltapoint.y / deltapoint.x; } if (!outtangentSet) { point1.x = inCurve.keys[i].time; point1.y = inCurve.keys[i].value; point2.x = inCurve.keys[i + 1].time; point2.y = inCurve.keys[i + 1].value; deltapoint = point2 - point1; outTangent = deltapoint.y / deltapoint.x; } key.inTangent = inTangent; key.outTangent = outTangent; outCurve.AddKey(key); } return outCurve; } /// /// Samples an AnimationCurve at regular intervals and returns the values as an array. /// Useful for pre-calculating curve values for performance-critical code. /// /// The curve to sample. /// Number of samples to take. Higher values provide more precision. /// Array of sampled values from 0 to 1. public static float[] GenerateCurveArray(this AnimationCurve self, int resolution = 256) { float[] returnArray = new float[resolution]; for (int j = 0; j < resolution; j++) { returnArray[j] = self.Evaluate(j / (float)resolution); } return returnArray; } } }