mirror of
https://github.com/ConjureETS/ProjectClubCore.git
synced 2026-03-24 09:30:58 +00:00
309 lines
8.7 KiB
C#
309 lines
8.7 KiB
C#
using Fusion;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Stats = Fusion.Simulation.Statistics;
|
|
using Fusion.StatsInternal;
|
|
|
|
public class FusionStatsMeterBar : FusionGraphBase
|
|
{
|
|
//public float WarningValueThreshold;
|
|
//public float ErrorValueThreshold;
|
|
|
|
|
|
public float HoldPeakTime = 0.1f;
|
|
public float DecayTime = 0.25f;
|
|
|
|
/// <summary>
|
|
/// Values greater than 0 will limit the meter to a range of 0 to MeterMax.
|
|
/// Value of 0 will adjust the max to the largest value occurance.
|
|
/// </summary>
|
|
[InlineHelp]
|
|
public int MeterMax = 0;
|
|
|
|
|
|
/// <summary>
|
|
/// Exposes the UI labels and controls of <see cref="FusionGraph"/>, so they may be modified if customizing this graph.
|
|
/// </summary>
|
|
[InlineHelp]
|
|
[SerializeField]
|
|
bool _showUITargets;
|
|
|
|
[DrawIf(nameof(_showUITargets), true, DrawIfHideType.Hide)]
|
|
public Text ValueLabel;
|
|
[DrawIf(nameof(_showUITargets), true, DrawIfHideType.Hide)]
|
|
public Image Bar;
|
|
|
|
|
|
//public string CurrentLabel;
|
|
//double _currentRawValue;
|
|
double _currentDisplayValue;
|
|
double _currentBarValue;
|
|
Color CurrentColor;
|
|
|
|
|
|
protected override Color BackColor => base.BackColor * new Color(.5f, .5f, .5f, 1);
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
protected override void OnValidate() {
|
|
base.OnValidate();
|
|
|
|
if (MeterMax < 0) {
|
|
MeterMax = 0;
|
|
}
|
|
|
|
if (Application.isPlaying == false) {
|
|
TryConnect();
|
|
_layoutDirty = true;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public override void Initialize() {
|
|
base.Initialize();
|
|
|
|
_max = MeterMax;
|
|
// Prefabs lose editor generated sprites - recreate as needed.
|
|
if (BackImage.sprite == null) {
|
|
BackImage.sprite = FusionStatsUtilities.MeterSprite;
|
|
Bar.sprite = BackImage.sprite;
|
|
}
|
|
|
|
// TODO: Can remove these later. Backwards compat for mask removal on Dec 30 2021
|
|
BackImage.type = Image.Type.Simple;
|
|
if (Bar.rectTransform.parent != BackImage.rectTransform.parent) {
|
|
var oldMask = Bar.transform.parent;
|
|
Bar.rectTransform.SetParent(BackImage.rectTransform.parent);
|
|
Bar.transform.SetSiblingIndex(BackImage.transform.GetSiblingIndex() + 1);
|
|
//Destroy(oldMask);
|
|
}
|
|
Bar.type = Image.Type.Filled;
|
|
Bar.fillMethod = Image.FillMethod.Horizontal;
|
|
Bar.fillAmount = 0;
|
|
}
|
|
|
|
double _lastImportedSampleTickTime;
|
|
double _max;
|
|
double _total;
|
|
float _lastPeakSetTime;
|
|
|
|
public override void Refresh() {
|
|
if (_layoutDirty) {
|
|
CalculateLayout();
|
|
}
|
|
|
|
var statsBuffer = StatsBuffer;
|
|
if (statsBuffer == null || statsBuffer.Count < 1) {
|
|
return;
|
|
}
|
|
|
|
// Awkward temp RPC handling
|
|
if (statsBuffer.DefaultVisualization == FusionGraphVisualization.CountHistogram) {
|
|
|
|
if (statsBuffer.Count > 0) {
|
|
|
|
int highestRpcsFoundForTick = 0;
|
|
float newestSampleTick = statsBuffer.GetSampleAtIndex(statsBuffer.Count - 1).TickValue;
|
|
var tick = newestSampleTick;
|
|
// Only look back at ticks we have not yet already looked at on previous updates.
|
|
if (newestSampleTick > _lastImportedSampleTickTime) {
|
|
int tickRpcCount = 0;
|
|
for (int i = statsBuffer.Count - 1; i >= 0; i--) {
|
|
var sampletick = statsBuffer.GetSampleAtIndex(i).TickValue;
|
|
|
|
if (sampletick > _lastImportedSampleTickTime) {
|
|
// If we are now looking at samples from a different tick that previous for loop, reset to get count for this tick now.
|
|
if (sampletick != tick) {
|
|
tick = sampletick;
|
|
// Capture the RPC count for the last recorded tick if it is the new high.
|
|
if (tickRpcCount > highestRpcsFoundForTick) {
|
|
highestRpcsFoundForTick = tickRpcCount;
|
|
}
|
|
tickRpcCount = 0;
|
|
}
|
|
tickRpcCount++;
|
|
_total++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
_lastImportedSampleTickTime = newestSampleTick;
|
|
}
|
|
|
|
SetValue(highestRpcsFoundForTick);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (statsBuffer.Count > 0) {
|
|
var value = statsBuffer.GetSampleAtIndex(statsBuffer.Count - 1);
|
|
if (value.TickValue == _fusionStats.Runner.Simulation.LatestServerState.Tick) {
|
|
SetValue(value.FloatValue);
|
|
} else {
|
|
SetValue(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void LateUpdate() {
|
|
|
|
if (DecayTime <= 0) {
|
|
return;
|
|
}
|
|
|
|
if (_currentBarValue <= 0) {
|
|
return;
|
|
}
|
|
|
|
if (Time.time < _lastPeakSetTime + HoldPeakTime) {
|
|
return;
|
|
}
|
|
|
|
double decayedVal = System.Math.Max(_currentBarValue - Time.deltaTime / DecayTime * _max, 0);
|
|
SetBar(decayedVal);
|
|
|
|
}
|
|
|
|
public void SetValue(double rawvalue) {
|
|
|
|
var info = StatSourceInfo;
|
|
|
|
double multiplied = rawvalue * info.Multiplier;
|
|
|
|
if (MeterMax == 0) {
|
|
if (multiplied > _max) {
|
|
_max = multiplied;
|
|
}
|
|
}
|
|
|
|
|
|
double clampedValue = System.Math.Max(System.Math.Min(multiplied, _max), 0);
|
|
var roundedValue = System.Math.Round(clampedValue, info.Decimals);
|
|
var newDisplayValue = _total > 0 ? _total : roundedValue;
|
|
|
|
if (clampedValue >= _currentBarValue) {
|
|
_lastPeakSetTime = Time.time;
|
|
}
|
|
|
|
if (newDisplayValue != _currentDisplayValue) {
|
|
ValueLabel.text = _total > 0 ? _total.ToString() : clampedValue.ToString();
|
|
_currentDisplayValue = newDisplayValue;
|
|
}
|
|
|
|
// Only set values greater than the current shown value when using decay.
|
|
if (DecayTime >= 0 && clampedValue <= _currentBarValue) {
|
|
return;
|
|
}
|
|
|
|
if (clampedValue != _currentBarValue) {
|
|
SetBar(clampedValue);
|
|
}
|
|
|
|
}
|
|
|
|
void SetBar(double value) {
|
|
|
|
var fusionStats = _fusionStats;
|
|
|
|
Bar.fillAmount = (float)(value / _max);
|
|
|
|
_currentBarValue = value;
|
|
|
|
if (value < WarnThreshold) {
|
|
var GoodColor = fusionStats.GraphColorGood;
|
|
if (CurrentColor != GoodColor) {
|
|
CurrentColor = GoodColor;
|
|
Bar.color = GoodColor;
|
|
}
|
|
} else if (value < ErrorThreshold) {
|
|
var WarnColor = fusionStats.GraphColorWarn;
|
|
if (CurrentColor != WarnColor) {
|
|
Bar.color = WarnColor;
|
|
CurrentColor = WarnColor;
|
|
}
|
|
} else {
|
|
var ErrorColor = fusionStats.GraphColorBad;
|
|
if (CurrentColor != ErrorColor) {
|
|
Bar.color = ErrorColor;
|
|
CurrentColor = ErrorColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void CalculateLayout() {
|
|
|
|
_layoutDirty = false;
|
|
|
|
// Special padding handling because Arial vertically sits below center.
|
|
var pad = LabelTitle.transform.parent.GetComponent<RectTransform>().rect.height * .2f;
|
|
LabelTitle.rectTransform.offsetMax = new Vector2(0, -pad);
|
|
LabelTitle.rectTransform.offsetMin = new Vector2(PAD, pad * 1.2f);
|
|
|
|
ValueLabel.rectTransform.offsetMax = new Vector2(-PAD, -pad);
|
|
ValueLabel.rectTransform.offsetMin = new Vector2(0, pad * 1.2f);
|
|
|
|
ApplyTitleText();
|
|
}
|
|
|
|
// unfinished
|
|
public static FusionStatsMeterBar Create(
|
|
RectTransform parent,
|
|
FusionStats fusionStats,
|
|
Stats.StatSourceTypes statSourceType,
|
|
int statId,
|
|
float warnThreshold,
|
|
float alertThreshold
|
|
) {
|
|
|
|
var info = Stats.GetDescription(statSourceType, statId);
|
|
var barRT = parent.CreateRectTransform(info.LongName, true);
|
|
var bar = barRT.gameObject.AddComponent<FusionStatsMeterBar>();
|
|
bar.StatSourceInfo = info;
|
|
bar._fusionStats = fusionStats;
|
|
//bar.WarningValueThreshold = warnThreshold;
|
|
//bar.ErrorValueThreshold = alertThreshold;
|
|
bar._statSourceType = statSourceType;
|
|
bar._statId = statId;
|
|
bar.GenerateMeter();
|
|
return bar;
|
|
}
|
|
|
|
public void GenerateMeter() {
|
|
|
|
var info = Stats.GetDescription(_statSourceType, _statId);
|
|
var backRT = transform.CreateRectTransform("Back", true);
|
|
BackImage = backRT.gameObject.AddComponent<Image>();
|
|
BackImage.raycastTarget = false;
|
|
BackImage.sprite = FusionStatsUtilities.MeterSprite;
|
|
BackImage.color = BackColor;
|
|
BackImage.type = Image.Type.Simple;
|
|
var barRT = transform.CreateRectTransform("Bar", true);
|
|
Bar = barRT.gameObject.AddComponent<Image>();
|
|
Bar.raycastTarget = false;
|
|
Bar.sprite = BackImage.sprite;
|
|
Bar.color = _fusionStats.GraphColorGood;
|
|
Bar.type = Image.Type.Filled;
|
|
Bar.fillMethod = Image.FillMethod.Horizontal;
|
|
Bar.fillAmount = 0;
|
|
|
|
var titleRT = transform.CreateRectTransform("Label", true)
|
|
.ExpandAnchor()
|
|
.SetAnchors(0.0f, 0.5f, 0.0f,1.0f)
|
|
.SetOffsets(6, -6, 6, -6);
|
|
|
|
|
|
LabelTitle = titleRT.AddText(info.LongName, TextAnchor.MiddleLeft, _fusionStats.FontColor);
|
|
LabelTitle.alignByGeometry = false;
|
|
|
|
var valueRT = transform.CreateRectTransform("Value", true)
|
|
.ExpandAnchor()
|
|
.SetAnchors(0.5f, 1.0f, 0.0f, 1.0f)
|
|
.SetOffsets(6, -6, 6, -6);
|
|
|
|
ValueLabel = valueRT.AddText("0.0", TextAnchor.MiddleRight, _fusionStats.FontColor);
|
|
ValueLabel.alignByGeometry = false;
|
|
|
|
}
|
|
|
|
}
|