171 lines
3.1 KiB
C#
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);
|
|
}
|
|
}
|