using System.Collections.Generic;
using UnityEngine;
namespace OM
{
///
/// Represents a single named animation curve.
/// Used within the CurvesLibrary to store and categorize predefined curves.
/// Marked as Serializable so it can be viewed and edited in the Unity Inspector
/// when part of a list within a ScriptableObject like CurvesLibrary.
///
[System.Serializable]
public class CurveData
{
///
/// The user-defined name for this animation curve (e.g., "Fast Bounce", "Linear Fade").
/// This field is serialized and editable in the Inspector.
///
[SerializeField] private string name;
///
/// The actual AnimationCurve data defining the curve's shape.
/// This field is serialized and editable in the Inspector using Unity's curve editor.
///
[SerializeField] private AnimationCurve curve;
///
/// Gets or sets the name of this curve data entry.
///
public string Name
{
get => name;
set => name = value; // Allows renaming, e.g., in a custom editor.
}
///
/// Gets or sets the AnimationCurve associated with this entry.
///
public AnimationCurve Curve
{
get => curve;
set => curve = value; // Allows changing the curve data.
}
}
///
/// A ScriptableObject acting as a central library for storing predefined AnimationCurves.
/// It uses a Singleton pattern (`Instance`) for easy access from anywhere.
/// Curves are categorized into Lerp, Bounce, and Custom lists.
/// Provides methods to retrieve curves by name and add new custom curves (Editor-only).
///
[CreateAssetMenu(fileName = "CurvesLibrary", menuName = "OM/CurvesLibrary")] // Allows creating instances via Assets/Create menu.
public class CurvesLibrary : ScriptableObject
{
// --- Singleton Implementation ---
private static CurvesLibrary _instance;
///
/// Provides global access to the single CurvesLibrary instance.
/// Loads the "CurvesLibrary" asset from the Resources folder if not already loaded.
/// Returns null if the asset cannot be found in Resources.
///
public static CurvesLibrary Instance
{
get
{
if (_instance == null)
{
// Attempt to load the asset from any "Resources" folder.
_instance = Resources.Load("CurvesLibrary");
if (_instance == null)
{
Debug.LogError("CurvesLibrary asset not found in Resources folder. Please create one via Assets/Create/OM/CurvesLibrary and place it in a Resources folder.");
}
}
return _instance;
}
}
///
/// List storing curves typically used for standard interpolation or fading (e.g., linear, ease-in, ease-out).
/// Editable in the Inspector.
///
[SerializeField] private List lerpCurves = new List();
///
/// List storing curves often used for bounce or overshoot effects.
/// Editable in the Inspector.
///
[SerializeField] private List bounceCurves = new List();
///
/// List storing custom user-defined curves, often added programmatically via AddCurve or manually in the Inspector.
/// Editable in the Inspector.
///
[SerializeField] private List customCurves = new List();
///
/// Gets the list of Lerp-type curves.
///
public List LerpCurves => lerpCurves;
///
/// Gets the list of Bounce-type curves.
///
public List BounceCurves => bounceCurves;
///
/// Gets the list of Custom-type curves.
///
public List CustomCurves => customCurves;
///
/// Retrieves an AnimationCurve by its exact name.
/// Searches through LerpCurves, BounceCurves, and CustomCurves in that order.
///
/// The case-sensitive name of the curve to find.
/// The found AnimationCurve, or a default linear EaseInOut curve if the name is not found in any list.
public AnimationCurve GetCurveByName(string curveName)
{
// Search Lerp curves first
foreach (var curveData in lerpCurves)
{
if (curveData.Name == curveName) return curveData.Curve;
}
// Search Bounce curves next
foreach (var curveData in bounceCurves)
{
if (curveData.Name == curveName) return curveData.Curve;
}
// Search Custom curves last
foreach (var curveData in customCurves)
{
if (curveData.Name == curveName) return curveData.Curve;
}
// Fallback if not found
Debug.LogWarning($"Curve with name '{curveName}' not found in CurvesLibrary. Returning default EaseInOut curve.");
return AnimationCurve.EaseInOut(0, 0, 1, 1); // Default fallback curve.
}
///
/// Adds a new curve to the `customCurves` list.
/// This method is intended for use within the Unity Editor (e.g., from a custom property drawer).
/// It handles Undo recording, marking the asset as dirty, saving assets, and selecting/pinging the library asset.
///
/// The base name for the new curve (a count suffix will be added).
/// The AnimationCurve data to add.
public void AddCurve(string curveName, AnimationCurve curve)
{
#if UNITY_EDITOR
// Record the change for Undo/Redo functionality.
UnityEditor.Undo.RecordObject(this, "Add Curve to Library");
#endif
// Add the new curve data to the custom list, appending the current count to the name for uniqueness.
customCurves.Add(new CurveData { Name = curveName + $" ({customCurves.Count})", Curve = curve });
#if UNITY_EDITOR
// Mark this ScriptableObject as dirty so Unity knows it needs to be saved.
UnityEditor.EditorUtility.SetDirty(this);
// Save the changes to the asset database.
UnityEditor.AssetDatabase.SaveAssets();
// Optionally select and ping the asset in the Project window for user feedback.
UnityEditor.Selection.activeObject = this;
UnityEditor.EditorGUIUtility.PingObject(this);
#endif
}
}
}