Files
butchers-games-test/Assets/Scripts/Game/App/PerformanceManager.cs
T
Boris Nikolaev 5f1e94b653 add project files
2026-08-14 01:58:31 +03:00

171 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using OHM.UnityToolkit;
public class PerformanceManager : UniqueInstance<PerformanceManager>
{
public enum QualityLevelType
{
AUTO = 0,
MANUAL = 1
}
[Serializable]
public class QualityLevel
{
public int engineQualityLevel;
public float fixedTimeStep = 0.01f;
}
public List<QualityLevel> qualityLevels;
private AppController _app;
public float refreshRate = 1f;
public float criticalFpsThreashold;
public float lowerQualityCriticalCount = 5f;
private int _frameCount;
private float _timeAccum;
private int _criticalCount;
public int QualityIndex { get; private set; } = -1;
public QualityLevelType LevelType { get; private set; }
public bool RecordPerformances { get; private set; }
public float LastAverageFps { get; set; } = 60f;
public event Action OnQualityChange;
public event Action OnRecordingChange;
protected override void AwakeInstance()
{
base.AwakeInstance();
LevelType = QualityLevelType.AUTO;
if (qualityLevels != null && qualityLevels.Count > 0)
{
ApplyQuality(qualityLevels.Count - 1);
}
}
private void Start()
{
_app = GetComponentInParent<AppController>();
if (_app == null)
{
return;
}
_app.coreGame.onGameStarted.AddListener(StartRecord);
_app.coreGame.onGameOver.AddListener(StopRecord);
}
private void StopRecord()
{
SetRecordPerformances(record: false);
_criticalCount = 0;
}
private void StartRecord()
{
SetRecordPerformances(record: true);
}
private void ApplyQuality(int index)
{
if (QualityIndex == index)
{
return;
}
QualityIndex = index;
QualityLevel level = qualityLevels[index];
Time.fixedDeltaTime = level.fixedTimeStep;
QualitySettings.SetQualityLevel(level.engineQualityLevel, applyExpensiveChanges: true);
if (this.OnQualityChange != null)
{
this.OnQualityChange();
}
}
public void ForceQuality(int index)
{
LevelType = QualityLevelType.MANUAL;
ApplyQuality(index);
}
public void SetAutoQuality()
{
LevelType = QualityLevelType.AUTO;
if (qualityLevels != null && qualityLevels.Count > 0)
{
ApplyQuality(qualityLevels.Count - 1);
}
}
private void Update()
{
UpdatePerformances();
}
public void SetRecordPerformances(bool record)
{
RecordPerformances = record;
if (this.OnRecordingChange != null)
{
this.OnRecordingChange();
}
_criticalCount = 0;
}
private void UpdatePerformances()
{
if (!RecordPerformances || LevelType != QualityLevelType.AUTO)
{
_criticalCount = 0;
return;
}
if (QualityIndex < 1)
{
return;
}
_frameCount++;
_timeAccum += Time.unscaledDeltaTime;
if (_timeAccum <= refreshRate)
{
return;
}
LastAverageFps = _frameCount / _timeAccum;
OnNewPerfValue();
}
private void OnNewPerfValue()
{
_frameCount = 0;
_timeAccum = 0f;
if (LastAverageFps >= criticalFpsThreashold)
{
_criticalCount = 0;
return;
}
_criticalCount++;
if (_criticalCount >= lowerQualityCriticalCount)
{
LowerQuality();
_criticalCount = 0;
}
}
private void LowerQuality()
{
int index = QualityIndex - 1;
ApplyQuality(index);
Debug.Log("Lowering quality to " + index);
}
}