csharp/1ZouLTReX1/FP-MOG/top%20down%20shooter/Assets/Scripts/Utils/FloatRollingAverage.cs

FloatRollingAverage.cs
using UnityEngine;

public clast FloatRollingAverage
{
    public float latest { get; private set; }
    public float max { get; private set; }
    public float min { get; private set; }
    public float average { get; private set; }
    public float stdDeviation { get; private set; }

    public CircularList GetData()
    {
        return m_Entries;
    }

    public FloatRollingAverage(int windowSize = 64)
    {
        m_Entries = new CircularList(windowSize);
    }

    public void Update(float value)
    {
        latest = value;

        if (m_Entries.Count == m_Entries.Capacity)
        {
            var oldValue = m_Entries[0];

            if(oldValue == min || oldValue == max)
            {
                // Recalculate min and max
                min = float.MaxValue;
                max = float.MinValue;
                for (int i = 0; i < m_Entries.Capacity; ++i)
                {
                    var entry = m_Entries[i];
                    if (entry < min)
                        min = m_Entries[i];
                    if (entry > max)
                        max = m_Entries[i];
                }
            }

            m_Sum -= oldValue;
            m_SqrSum -= oldValue * oldValue;
        }

        if (value > max)
            max = value;

        if (value < min)
            min = value;

        m_Entries.Add(value);
        var samples = m_Entries.Count;

        m_Sum += value;
        m_SqrSum += value * value;

        average = m_Sum / samples;
        float f = (m_SqrSum - m_Sum * m_Sum / samples) / samples;   
        stdDeviation = f >= 0 ? Mathf.Sqrt(f) : 0;
    }

    public void Reset()
    {
        m_Entries.Clear();
        latest = 0;
        average = 0;
        max = 0;
        min = 0;
        stdDeviation = 0;

        m_Sum = 0;
        m_SqrSum = 0;
    }

    float m_Sum;
    float m_SqrSum;

    CircularList m_Entries;
}