using System; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Serialization; public interface IResettableSettingValue{ public void Verify(); public void SmoothAndEase(); public void Initialize(); } [Serializable] public class SettingValue : IResettableSettingValue{ [HorizontalGroup("Settings", width: .3f), VerticalGroup("Settings/Value"), BoxGroup("Settings/Value/Value"), LabelText("Target")] public T targetValue; [HorizontalGroup("Settings"), VerticalGroup("Settings/Value"), BoxGroup("Settings/Value/Value"), LabelText("Current")] public T currentValue; [HorizontalGroup("Settings"), VerticalGroup("Settings/Smoothing"), BoxGroup("Settings/Smoothing/Smoothing"), LabelText("Target"), ShowIf("@IsSmoothable()")] public float targetSmoothing; // Smoothing changes how fast the value is changed. [HorizontalGroup("Settings"), VerticalGroup("Settings/Easing"), BoxGroup("Settings/Easing/Easing"), LabelText("Target"), ShowIf("@IsSmoothable()")] public float targetEasing; // Easing changes how fast smoothing is changed, when given a new value. public T Value{ get => currentValue; set{ if (IsSmoothable()) { targetValue = value; } else { currentValue = value; targetValue = value; } } } [HorizontalGroup("Settings"), VerticalGroup("Settings/Smoothing"), BoxGroup("Settings/Smoothing/Smoothing"), LabelText("Current"), ShowIf("@IsSmoothable()")] public float currentSmoothing; [HorizontalGroup("Settings"), VerticalGroup("Settings/Value"), BoxGroup("Settings/Value/Value"), LabelText("Default")] public T defaultValue; [HorizontalGroup("Settings"), VerticalGroup("Settings/Smoothing"), BoxGroup("Settings/Smoothing/Smoothing"), LabelText("Default"), ShowIf("@IsSmoothable()")] public float defaultSmoothing; [HorizontalGroup("Settings"), VerticalGroup("Settings/Easing"), BoxGroup("Settings/Easing/Easing"), LabelText("Default"), ShowIf("@IsSmoothable()")] public float defaultEasing; private float refVelFloat; // For use with SmoothDamp private Vector3 refVelV3; // For use with SmoothDamp private Vector2 refVelV2; // For use with SmoothDamp private bool verified; bool IsSmoothable(){ return (typeof(T) == typeof(float) || typeof(T) == typeof(Vector2) || typeof(T) == typeof(Vector3) || typeof(T) == typeof(Vector4) || typeof(T) == typeof(Quaternion) ); } public SettingValue(T initValue, float defaultEasing = 2f, float defaultSmoothing = 1f){ targetValue = initValue; defaultValue = initValue; this.defaultSmoothing = defaultSmoothing; this.defaultEasing = defaultEasing; targetEasing = defaultEasing; targetSmoothing = defaultSmoothing; currentSmoothing = targetSmoothing; currentValue = targetValue; refVelFloat = 0; refVelV3 = default; refVelV2 = default; } public void Verify(){ if (targetValue.Equals(currentValue) == false) { Debug.LogWarning($"A SettingValue ({this}) doesn't have its current and target value matching. This should have been set!"); } verified = true; } public void SmoothAndEase(){ if (!verified) { Debug.LogWarning($"A SettingValue ({this}) wasn't verified before being smoothed and eased. What's up with that?"); } currentSmoothing = Mathf.MoveTowards(currentSmoothing, targetSmoothing, targetEasing * targetEasing * Time.deltaTime); if (typeof(T) == typeof(float)) { currentValue = (T)(object)Mathf.SmoothDamp((float)(object)currentValue, (float)(object)targetValue, ref refVelFloat, currentSmoothing * Time.deltaTime); } if (typeof(T) == typeof(Vector2)) { currentValue = (T)(object)Vector2.SmoothDamp((Vector2)(object)currentValue, (Vector2)(object)targetValue, ref refVelV2, currentSmoothing * currentSmoothing * Time.deltaTime); } if (typeof(T) == typeof(Vector3)) { currentValue = (T)(object)Vector3.SmoothDamp((Vector3)(object)currentValue, (Vector3)(object)targetValue, ref refVelV3, currentSmoothing * currentSmoothing * Time.deltaTime); } if (typeof(T) == typeof(Vector4) || typeof(T) == typeof(Quaternion)) { // I have... zero clue if this will work. There is no Vector4 or Quaternion SmoothDamp Vector3 v3value = Vector3.SmoothDamp((Vector4)(object)currentValue, (Vector4)(object)targetValue, ref refVelV3, currentSmoothing * currentSmoothing * Time.deltaTime); float v4value = Mathf.SmoothDamp(((Vector4)(object)currentValue).z, ((Vector4)(object)targetValue).z, ref refVelFloat, currentSmoothing * currentSmoothing * Time.deltaTime); currentValue = (T)(object)new Vector4(v3value.x, v3value.y, v3value.z, v4value); } } public void Initialize(){ currentValue = targetValue; defaultValue = targetValue; defaultSmoothing = targetSmoothing; defaultEasing = targetEasing; currentSmoothing = targetSmoothing; } }