Keep local version of files

This commit is contained in:
2026-10-08 00:49:10 +05:30
parent 7fa0621ff8
commit 053665c690
7343 changed files with 5470578 additions and 5470528 deletions
+217 -217
View File
@@ -1,217 +1,217 @@
using System;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Mirror
{
public enum GraphAggregationMode
{
Sum,
Average,
PerSecond,
Min,
Max
}
public abstract class BaseUIGraph : MonoBehaviour
{
static readonly int MaxValue = Shader.PropertyToID("_MaxValue");
static readonly int GraphData = Shader.PropertyToID("_GraphData");
static readonly int CategoryCount = Shader.PropertyToID("_CategoryCount");
static readonly int Colors = Shader.PropertyToID("_CategoryColors");
static readonly int Width = Shader.PropertyToID("_Width");
static readonly int DataStart = Shader.PropertyToID("_DataStart");
public Material Material;
public Graphic Renderer;
[Range(1, 64)]
public int Points = 64;
public float SecondsPerPoint = 1;
public Color[] CategoryColors = new[] { Color.cyan };
public bool IsStacked;
public Text[] LegendTexts;
[Header("Diagnostics")]
[ReadOnly, SerializeField]
Material runtimeMaterial;
float[] graphData;
// graphData is a circular buffer, this is the offset to get the 0-index
int graphDataStartIndex;
// Is graphData dirty and needs to be set to the material
bool isGraphDataDirty;
// currently aggregating data to be added to the graph soon
float[] aggregatingData;
GraphAggregationMode[] aggregatingModes;
// Counts for avg aggregation mode
int[] aggregatingDataCounts;
// How much time has elapsed since the last aggregation finished
float aggregatingTime;
int DataLastIndex => (graphDataStartIndex - 1 + Points) % Points;
void Awake()
{
Renderer.material = runtimeMaterial = Instantiate(Material);
graphData = new float[Points * CategoryColors.Length];
aggregatingData = new float[CategoryColors.Length];
aggregatingDataCounts = new int[CategoryColors.Length];
aggregatingModes = new GraphAggregationMode[CategoryColors.Length];
isGraphDataDirty = true;
}
protected virtual void OnValidate()
{
if (Renderer == null)
Renderer = GetComponent<Graphic>();
}
protected virtual void Update()
{
for (int i = 0; i < CategoryColors.Length; i++)
{
CollectData(i, out float value, out GraphAggregationMode mode);
// we probably don't need negative values, so lets skip supporting it
if (value < 0)
{
Debug.LogWarning("Graphing negative values is not supported.");
value = 0;
}
if (mode != aggregatingModes[i])
{
aggregatingModes[i] = mode;
ResetCurrent(i);
}
switch (mode)
{
case GraphAggregationMode.Average:
case GraphAggregationMode.Sum:
case GraphAggregationMode.PerSecond:
aggregatingData[i] += value;
aggregatingDataCounts[i]++;
break;
case GraphAggregationMode.Min:
if (aggregatingData[i] > value)
aggregatingData[i] = value;
break;
case GraphAggregationMode.Max:
if (value > aggregatingData[i])
aggregatingData[i] = value;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
aggregatingTime += Time.deltaTime;
if (aggregatingTime > SecondsPerPoint)
{
graphDataStartIndex = (graphDataStartIndex + 1) % Points;
ClearDataAt(DataLastIndex);
for (int i = 0; i < CategoryColors.Length; i++)
{
float value = aggregatingData[i];
switch (aggregatingModes[i])
{
case GraphAggregationMode.Sum:
case GraphAggregationMode.Min:
case GraphAggregationMode.Max:
// do nothing!
break;
case GraphAggregationMode.Average:
value /= aggregatingDataCounts[i];
break;
case GraphAggregationMode.PerSecond:
value /= aggregatingTime;
break;
default:
throw new ArgumentOutOfRangeException();
}
SetCurrentGraphData(i, value);
ResetCurrent(i);
}
aggregatingTime = 0;
}
}
void ResetCurrent(int i)
{
switch (aggregatingModes[i])
{
case GraphAggregationMode.Min:
aggregatingData[i] = float.MaxValue;
break;
default:
aggregatingData[i] = 0;
break;
}
aggregatingDataCounts[i] = 0;
}
protected virtual string FormatValue(float value) => $"{value:N1}";
protected abstract void CollectData(int category, out float value, out GraphAggregationMode mode);
void SetCurrentGraphData(int c, float value)
{
graphData[DataLastIndex * CategoryColors.Length + c] = value;
isGraphDataDirty = true;
}
void ClearDataAt(int i)
{
for (int c = 0; c < CategoryColors.Length; c++)
graphData[i * CategoryColors.Length + c] = 0;
isGraphDataDirty = true;
}
public void LateUpdate()
{
if (isGraphDataDirty)
{
runtimeMaterial.SetInt(Width, Points);
runtimeMaterial.SetInt(DataStart, graphDataStartIndex);
float max = 1;
if (IsStacked)
for (int x = 0; x < Points; x++)
{
float total = 0;
for (int c = 0; c < CategoryColors.Length; c++)
total += graphData[x * CategoryColors.Length + c];
if (total > max)
max = total;
}
else
for (int i = 0; i < graphData.Length; i++)
{
float v = graphData[i];
if (v > max)
max = v;
}
max = AdjustMaxValue(max);
for (int i = 0; i < LegendTexts.Length; i++)
{
Text legendText = LegendTexts[i];
float pct = (float)i / (LegendTexts.Length - 1);
legendText.text = FormatValue(max * pct);
}
runtimeMaterial.SetFloat(MaxValue, max);
runtimeMaterial.SetFloatArray(GraphData, graphData);
runtimeMaterial.SetInt(CategoryCount, CategoryColors.Length);
runtimeMaterial.SetColorArray(Colors, CategoryColors);
isGraphDataDirty = false;
}
}
protected virtual float AdjustMaxValue(float max) => Mathf.Ceil(max);
}
}
using System;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Mirror
{
public enum GraphAggregationMode
{
Sum,
Average,
PerSecond,
Min,
Max
}
public abstract class BaseUIGraph : MonoBehaviour
{
static readonly int MaxValue = Shader.PropertyToID("_MaxValue");
static readonly int GraphData = Shader.PropertyToID("_GraphData");
static readonly int CategoryCount = Shader.PropertyToID("_CategoryCount");
static readonly int Colors = Shader.PropertyToID("_CategoryColors");
static readonly int Width = Shader.PropertyToID("_Width");
static readonly int DataStart = Shader.PropertyToID("_DataStart");
public Material Material;
public Graphic Renderer;
[Range(1, 64)]
public int Points = 64;
public float SecondsPerPoint = 1;
public Color[] CategoryColors = new[] { Color.cyan };
public bool IsStacked;
public Text[] LegendTexts;
[Header("Diagnostics")]
[ReadOnly, SerializeField]
Material runtimeMaterial;
float[] graphData;
// graphData is a circular buffer, this is the offset to get the 0-index
int graphDataStartIndex;
// Is graphData dirty and needs to be set to the material
bool isGraphDataDirty;
// currently aggregating data to be added to the graph soon
float[] aggregatingData;
GraphAggregationMode[] aggregatingModes;
// Counts for avg aggregation mode
int[] aggregatingDataCounts;
// How much time has elapsed since the last aggregation finished
float aggregatingTime;
int DataLastIndex => (graphDataStartIndex - 1 + Points) % Points;
void Awake()
{
Renderer.material = runtimeMaterial = Instantiate(Material);
graphData = new float[Points * CategoryColors.Length];
aggregatingData = new float[CategoryColors.Length];
aggregatingDataCounts = new int[CategoryColors.Length];
aggregatingModes = new GraphAggregationMode[CategoryColors.Length];
isGraphDataDirty = true;
}
protected virtual void OnValidate()
{
if (Renderer == null)
Renderer = GetComponent<Graphic>();
}
protected virtual void Update()
{
for (int i = 0; i < CategoryColors.Length; i++)
{
CollectData(i, out float value, out GraphAggregationMode mode);
// we probably don't need negative values, so lets skip supporting it
if (value < 0)
{
Debug.LogWarning("Graphing negative values is not supported.");
value = 0;
}
if (mode != aggregatingModes[i])
{
aggregatingModes[i] = mode;
ResetCurrent(i);
}
switch (mode)
{
case GraphAggregationMode.Average:
case GraphAggregationMode.Sum:
case GraphAggregationMode.PerSecond:
aggregatingData[i] += value;
aggregatingDataCounts[i]++;
break;
case GraphAggregationMode.Min:
if (aggregatingData[i] > value)
aggregatingData[i] = value;
break;
case GraphAggregationMode.Max:
if (value > aggregatingData[i])
aggregatingData[i] = value;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
aggregatingTime += Time.deltaTime;
if (aggregatingTime > SecondsPerPoint)
{
graphDataStartIndex = (graphDataStartIndex + 1) % Points;
ClearDataAt(DataLastIndex);
for (int i = 0; i < CategoryColors.Length; i++)
{
float value = aggregatingData[i];
switch (aggregatingModes[i])
{
case GraphAggregationMode.Sum:
case GraphAggregationMode.Min:
case GraphAggregationMode.Max:
// do nothing!
break;
case GraphAggregationMode.Average:
value /= aggregatingDataCounts[i];
break;
case GraphAggregationMode.PerSecond:
value /= aggregatingTime;
break;
default:
throw new ArgumentOutOfRangeException();
}
SetCurrentGraphData(i, value);
ResetCurrent(i);
}
aggregatingTime = 0;
}
}
void ResetCurrent(int i)
{
switch (aggregatingModes[i])
{
case GraphAggregationMode.Min:
aggregatingData[i] = float.MaxValue;
break;
default:
aggregatingData[i] = 0;
break;
}
aggregatingDataCounts[i] = 0;
}
protected virtual string FormatValue(float value) => $"{value:N1}";
protected abstract void CollectData(int category, out float value, out GraphAggregationMode mode);
void SetCurrentGraphData(int c, float value)
{
graphData[DataLastIndex * CategoryColors.Length + c] = value;
isGraphDataDirty = true;
}
void ClearDataAt(int i)
{
for (int c = 0; c < CategoryColors.Length; c++)
graphData[i * CategoryColors.Length + c] = 0;
isGraphDataDirty = true;
}
public void LateUpdate()
{
if (isGraphDataDirty)
{
runtimeMaterial.SetInt(Width, Points);
runtimeMaterial.SetInt(DataStart, graphDataStartIndex);
float max = 1;
if (IsStacked)
for (int x = 0; x < Points; x++)
{
float total = 0;
for (int c = 0; c < CategoryColors.Length; c++)
total += graphData[x * CategoryColors.Length + c];
if (total > max)
max = total;
}
else
for (int i = 0; i < graphData.Length; i++)
{
float v = graphData[i];
if (v > max)
max = v;
}
max = AdjustMaxValue(max);
for (int i = 0; i < LegendTexts.Length; i++)
{
Text legendText = LegendTexts[i];
float pct = (float)i / (LegendTexts.Length - 1);
legendText.text = FormatValue(max * pct);
}
runtimeMaterial.SetFloat(MaxValue, max);
runtimeMaterial.SetFloatArray(GraphData, graphData);
runtimeMaterial.SetInt(CategoryCount, CategoryColors.Length);
runtimeMaterial.SetColorArray(Colors, CategoryColors);
isGraphDataDirty = false;
}
}
protected virtual float AdjustMaxValue(float max) => Mathf.Ceil(max);
}
}
@@ -1,21 +1,21 @@
fileFormatVersion: 2
guid: 0f7dbe0fe96842f3b3ec76d05d2bb24a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- Material: {fileID: 2100000, guid: 5f77111e39fad6240bbf2a93d735b648, type: 2}
- Renderer: {instanceID: 0}
- runtimeMaterial: {instanceID: 0}
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/BaseUIGraph.cs
uploadId: 736421
fileFormatVersion: 2
guid: 0f7dbe0fe96842f3b3ec76d05d2bb24a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- Material: {fileID: 2100000, guid: 5f77111e39fad6240bbf2a93d735b648, type: 2}
- Renderer: {instanceID: 0}
- runtimeMaterial: {instanceID: 0}
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/BaseUIGraph.cs
uploadId: 736421
@@ -1,40 +1,40 @@
using System;
using UnityEngine;
namespace Mirror
{
public class FpsMinMaxAvgGraph : BaseUIGraph
{
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
value = 1 / Time.deltaTime;
switch (category)
{
case 0:
mode = GraphAggregationMode.Average;
break;
case 1:
mode = GraphAggregationMode.Min;
break;
case 2:
mode = GraphAggregationMode.Max;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 3)
CategoryColors = new[]
{
Color.cyan, // avg
Color.red, // min
Color.green // max
};
IsStacked = false;
}
}
}
using System;
using UnityEngine;
namespace Mirror
{
public class FpsMinMaxAvgGraph : BaseUIGraph
{
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
value = 1 / Time.deltaTime;
switch (category)
{
case 0:
mode = GraphAggregationMode.Average;
break;
case 1:
mode = GraphAggregationMode.Min;
break;
case 2:
mode = GraphAggregationMode.Max;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 3)
CategoryColors = new[]
{
Color.cyan, // avg
Color.red, // min
Color.green // max
};
IsStacked = false;
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: 73bc3b929ec94537a8dbd67eb9d0c2c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/FpsMinMaxAvgGraph.cs
uploadId: 736421
fileFormatVersion: 2
guid: 73bc3b929ec94537a8dbd67eb9d0c2c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/FpsMinMaxAvgGraph.cs
uploadId: 736421
@@ -1,89 +1,89 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LineGraph
m_Shader: {fileID: 4800000, guid: e9fd6820072746bbaa3a83a449c31709, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _CategoryCount: 0
- _ColorMask: 15
- _Cutoff: 0.5
- _DataStart: 0
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _LineWidth: 1
- _MaxValue: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _Width: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LineGraph
m_Shader: {fileID: 4800000, guid: e9fd6820072746bbaa3a83a449c31709, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _CategoryCount: 0
- _ColorMask: 15
- _Cutoff: 0.5
- _DataStart: 0
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _LineWidth: 1
- _MaxValue: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _Width: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
@@ -1,15 +1,15 @@
fileFormatVersion: 2
guid: 5f77111e39fad6240bbf2a93d735b648
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/LineGraph.mat
uploadId: 736421
fileFormatVersion: 2
guid: 5f77111e39fad6240bbf2a93d735b648
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/LineGraph.mat
uploadId: 736421
@@ -1,85 +1,85 @@
using System;
using UnityEngine;
namespace Mirror
{
public class NetworkBandwidthGraph : BaseUIGraph
{
int dataIn;
int dataOut;
void Start()
{
// Ordering, Awake happens before NetworkDiagnostics reset
NetworkDiagnostics.InMessageEvent += OnReceive;
NetworkDiagnostics.OutMessageEvent += OnSend;
}
void OnEnable()
{
// If we've been inactive, clear counter
dataIn = 0;
dataOut = 0;
}
void OnDestroy()
{
NetworkDiagnostics.InMessageEvent -= OnReceive;
NetworkDiagnostics.OutMessageEvent -= OnSend;
}
void OnSend(NetworkDiagnostics.MessageInfo obj) => dataOut += obj.bytes;
void OnReceive(NetworkDiagnostics.MessageInfo obj) => dataIn += obj.bytes;
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
mode = GraphAggregationMode.PerSecond;
switch (category)
{
case 0:
value = dataIn;
dataIn = 0;
break;
case 1:
value = dataOut;
dataOut = 0;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
static readonly string[] Units = new[] { "B/s", "KiB/s", "MiB/s" };
const float UnitScale = 1024;
protected override string FormatValue(float value)
{
string selectedUnit = null;
for (int i = 0; i < Units.Length; i++)
{
string unit = Units[i];
selectedUnit = unit;
if (i > 0)
value /= UnitScale;
if (value < UnitScale)
break;
}
return $"{value:N0} {selectedUnit}";
}
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 2)
CategoryColors = new[]
{
Color.red, // min
Color.green // max
};
IsStacked = false;
}
}
}
using System;
using UnityEngine;
namespace Mirror
{
public class NetworkBandwidthGraph : BaseUIGraph
{
int dataIn;
int dataOut;
void Start()
{
// Ordering, Awake happens before NetworkDiagnostics reset
NetworkDiagnostics.InMessageEvent += OnReceive;
NetworkDiagnostics.OutMessageEvent += OnSend;
}
void OnEnable()
{
// If we've been inactive, clear counter
dataIn = 0;
dataOut = 0;
}
void OnDestroy()
{
NetworkDiagnostics.InMessageEvent -= OnReceive;
NetworkDiagnostics.OutMessageEvent -= OnSend;
}
void OnSend(NetworkDiagnostics.MessageInfo obj) => dataOut += obj.bytes;
void OnReceive(NetworkDiagnostics.MessageInfo obj) => dataIn += obj.bytes;
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
mode = GraphAggregationMode.PerSecond;
switch (category)
{
case 0:
value = dataIn;
dataIn = 0;
break;
case 1:
value = dataOut;
dataOut = 0;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
static readonly string[] Units = new[] { "B/s", "KiB/s", "MiB/s" };
const float UnitScale = 1024;
protected override string FormatValue(float value)
{
string selectedUnit = null;
for (int i = 0; i < Units.Length; i++)
{
string unit = Units[i];
selectedUnit = unit;
if (i > 0)
value /= UnitScale;
if (value < UnitScale)
break;
}
return $"{value:N0} {selectedUnit}";
}
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 2)
CategoryColors = new[]
{
Color.red, // min
Color.green // max
};
IsStacked = false;
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: e1ae19b97f0e4a5eb8cf5158d97506f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkBandwidthGraph.cs
uploadId: 736421
fileFormatVersion: 2
guid: e1ae19b97f0e4a5eb8cf5158d97506f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkBandwidthGraph.cs
uploadId: 736421
@@ -1,178 +1,178 @@
Shader "Mirror/NetworkGraphLines"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_Width ("Width", Int) = 0
_LineWidth ("Line Width", Float) = 0.005
_CategoryCount ("CategoryCount", Int) = 0
_MaxValue ("MaxValue", Float) = 1
_DataStart ("DataStart", Int) = 0
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex; // we dont use this, but unitys ui library expects the shader to have a texture
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
uint _Width;
half _LineWidth;
uint _CategoryCount;
uint _MaxValue;
uint _DataStart;
half _GraphData[64 /* max. 128 points */ * 8 /* max 8 categories */];
half4 _CategoryColors[8 /* max 8 categories */];
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
// Helper function to calculate the shortest distance from a point (p) to a line segment (from a to b)
float distanceToLineSegment(float2 p, float2 a, float2 b)
{
float2 ab = b - a;
float2 ap = p - a;
float t = saturate(dot(ap, ab) / dot(ab, ab));
// Clamp t between 0 and 1 to ensure we stay within the segment
float2 closestPoint = a + t * ab; // Find the closest point on the line segment
return length(p - closestPoint); // Return the distance from p to the closest point on the line
}
fixed4 frag(v2f IN) : SV_Target
{
uint wCur = (uint)(IN.texcoord.x * _Width);
uint wMin = wCur == 0 ? 0 : wCur - 1;
uint wMax = wCur == _Width - 1 ? wCur : wCur + 1;
float2 screenSize = _ScreenParams.xy;
// this scaling only works if the object is flat and not rotated - but thats fine
float2 pixelScale = float2(1 / ddx(IN.texcoord.x), 1 / ddy(IN.texcoord.y));
float2 screenSpaceUV = IN.texcoord * pixelScale;
half4 color = half4(0, 0, 0, 0);
// Loop through the graph's points
bool colored = false;
for (uint wNonOffset = wMin; wNonOffset < wMax && !colored; wNonOffset++)
{
uint w = (wNonOffset + _DataStart) % _Width;
// previous entry, unless it's the start, then we clamp to start
uint nextW = (w + 1) % _Width;
float texPosCurrentX = float(wNonOffset) / _Width;
float texPosPrevX = texPosCurrentX + 1.0f / _Width;
for (uint c = 0; c < _CategoryCount; c++)
{
float categoryValueCurrent = _GraphData[w * _CategoryCount + c] / _MaxValue;
float categoryValueNext = _GraphData[nextW * _CategoryCount + c] / _MaxValue;
float2 pointCurrent = float2(texPosCurrentX, categoryValueCurrent);
float2 pointNext = float2(texPosPrevX, categoryValueNext);
float distance = distanceToLineSegment(screenSpaceUV, pointCurrent * pixelScale,
pointNext * pixelScale);
if (distance < _LineWidth)
{
color = _CategoryColors[c];
colored = true;
break;
}
}
}
color *= IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
Shader "Mirror/NetworkGraphLines"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_Width ("Width", Int) = 0
_LineWidth ("Line Width", Float) = 0.005
_CategoryCount ("CategoryCount", Int) = 0
_MaxValue ("MaxValue", Float) = 1
_DataStart ("DataStart", Int) = 0
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex; // we dont use this, but unitys ui library expects the shader to have a texture
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
uint _Width;
half _LineWidth;
uint _CategoryCount;
uint _MaxValue;
uint _DataStart;
half _GraphData[64 /* max. 128 points */ * 8 /* max 8 categories */];
half4 _CategoryColors[8 /* max 8 categories */];
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
// Helper function to calculate the shortest distance from a point (p) to a line segment (from a to b)
float distanceToLineSegment(float2 p, float2 a, float2 b)
{
float2 ab = b - a;
float2 ap = p - a;
float t = saturate(dot(ap, ab) / dot(ab, ab));
// Clamp t between 0 and 1 to ensure we stay within the segment
float2 closestPoint = a + t * ab; // Find the closest point on the line segment
return length(p - closestPoint); // Return the distance from p to the closest point on the line
}
fixed4 frag(v2f IN) : SV_Target
{
uint wCur = (uint)(IN.texcoord.x * _Width);
uint wMin = wCur == 0 ? 0 : wCur - 1;
uint wMax = wCur == _Width - 1 ? wCur : wCur + 1;
float2 screenSize = _ScreenParams.xy;
// this scaling only works if the object is flat and not rotated - but thats fine
float2 pixelScale = float2(1 / ddx(IN.texcoord.x), 1 / ddy(IN.texcoord.y));
float2 screenSpaceUV = IN.texcoord * pixelScale;
half4 color = half4(0, 0, 0, 0);
// Loop through the graph's points
bool colored = false;
for (uint wNonOffset = wMin; wNonOffset < wMax && !colored; wNonOffset++)
{
uint w = (wNonOffset + _DataStart) % _Width;
// previous entry, unless it's the start, then we clamp to start
uint nextW = (w + 1) % _Width;
float texPosCurrentX = float(wNonOffset) / _Width;
float texPosPrevX = texPosCurrentX + 1.0f / _Width;
for (uint c = 0; c < _CategoryCount; c++)
{
float categoryValueCurrent = _GraphData[w * _CategoryCount + c] / _MaxValue;
float categoryValueNext = _GraphData[nextW * _CategoryCount + c] / _MaxValue;
float2 pointCurrent = float2(texPosCurrentX, categoryValueCurrent);
float2 pointNext = float2(texPosPrevX, categoryValueNext);
float distance = distanceToLineSegment(screenSpaceUV, pointCurrent * pixelScale,
pointNext * pixelScale);
if (distance < _LineWidth)
{
color = _CategoryColors[c];
colored = true;
break;
}
}
}
color *= IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
@@ -1,10 +1,10 @@
fileFormatVersion: 2
guid: e9fd6820072746bbaa3a83a449c31709
timeCreated: 1725809505
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkGraphLines.shader
uploadId: 736421
fileFormatVersion: 2
guid: e9fd6820072746bbaa3a83a449c31709
timeCreated: 1725809505
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkGraphLines.shader
uploadId: 736421
@@ -1,138 +1,138 @@
Shader "Mirror/NetworkGraphStacked"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_Width ("Width", Int) = 0
_CategoryCount ("CategoryCount", Int) = 0
_MaxValue ("MaxValue", Float) = 1
_DataStart ("DataStart", Int) = 0
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex; // we dont use this, but unitys ui library expects the shader to have a texture
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
uint _Width;
uint _CategoryCount;
uint _MaxValue;
uint _DataStart;
half _GraphData[64 /* max. 64 points */ * 8 /* max 8 categories */];
half4 _CategoryColors[8 /* max 8 categories */];
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
uint w = ((uint)(IN.texcoord.x * _Width) + _DataStart) % _Width;
half4 color = half4(0, 0, 0, 0);
float totalValue = 0;
for (uint c = 0; c < _CategoryCount; c++)
{
float categoryValue = _GraphData[w * _CategoryCount + c] / _MaxValue;
totalValue += categoryValue;
if (totalValue >= IN.texcoord.y)
{
color = _CategoryColors[c];
break;
}
}
color *= IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
Shader "Mirror/NetworkGraphStacked"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_Width ("Width", Int) = 0
_CategoryCount ("CategoryCount", Int) = 0
_MaxValue ("MaxValue", Float) = 1
_DataStart ("DataStart", Int) = 0
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex; // we dont use this, but unitys ui library expects the shader to have a texture
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
uint _Width;
uint _CategoryCount;
uint _MaxValue;
uint _DataStart;
half _GraphData[64 /* max. 64 points */ * 8 /* max 8 categories */];
half4 _CategoryColors[8 /* max 8 categories */];
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
uint w = ((uint)(IN.texcoord.x * _Width) + _DataStart) % _Width;
half4 color = half4(0, 0, 0, 0);
float totalValue = 0;
for (uint c = 0; c < _CategoryCount; c++)
{
float categoryValue = _GraphData[w * _CategoryCount + c] / _MaxValue;
totalValue += categoryValue;
if (totalValue >= IN.texcoord.y)
{
color = _CategoryColors[c];
break;
}
}
color *= IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
@@ -1,10 +1,10 @@
fileFormatVersion: 2
guid: b5b24284f35f4992bcd4cc43919267d7
timeCreated: 1724246251
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkGraphStacked.shader
uploadId: 736421
fileFormatVersion: 2
guid: b5b24284f35f4992bcd4cc43919267d7
timeCreated: 1724246251
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkGraphStacked.shader
uploadId: 736421
@@ -1,34 +1,34 @@
using System;
using UnityEngine;
namespace Mirror
{
public class NetworkPingGraph : BaseUIGraph
{
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
mode = GraphAggregationMode.Average;
switch (category)
{
case 0:
value = (float)NetworkTime.rtt * 1000f;
break;
case 1:
value = (float)NetworkTime.rttVariance * 1000f;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
protected override string FormatValue(float value) => $"{value:N0}ms";
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 2)
CategoryColors = new[] { Color.cyan, Color.yellow };
IsStacked = false;
}
}
}
using System;
using UnityEngine;
namespace Mirror
{
public class NetworkPingGraph : BaseUIGraph
{
protected override void CollectData(int category, out float value, out GraphAggregationMode mode)
{
mode = GraphAggregationMode.Average;
switch (category)
{
case 0:
value = (float)NetworkTime.rtt * 1000f;
break;
case 1:
value = (float)NetworkTime.rttVariance * 1000f;
break;
default:
throw new ArgumentOutOfRangeException($"{category} is not valid.");
}
}
protected override string FormatValue(float value) => $"{value:N0}ms";
protected override void OnValidate()
{
base.OnValidate();
if (CategoryColors.Length != 2)
CategoryColors = new[] { Color.cyan, Color.yellow };
IsStacked = false;
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: 14a68afedbbf4568b0decc5c3fe6dfd9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkPingGraph.cs
uploadId: 736421
fileFormatVersion: 2
guid: 14a68afedbbf4568b0decc5c3fe6dfd9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkPingGraph.cs
uploadId: 736421
@@ -1,315 +1,315 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Mirror.RemoteCalls;
using UnityEngine;
namespace Mirror
{
public class NetworkRuntimeProfiler : MonoBehaviour
{
[Serializable]
public class Sorter : IComparer<Stat>
{
public SortBy Order;
public int Compare(Stat a, Stat b)
{
if (a == null)
return 1;
if (b == null)
return -1;
// Compare B to A for desc order
switch (Order)
{
case SortBy.RecentBytes:
return b.RecentBytes.CompareTo(a.RecentBytes);
case SortBy.RecentCount:
return b.RecentCount.CompareTo(a.RecentCount);
case SortBy.TotalBytes:
return b.TotalBytes.CompareTo(a.TotalBytes);
case SortBy.TotalCount:
return b.TotalCount.CompareTo(a.TotalCount);
default:
throw new ArgumentOutOfRangeException();
}
}
}
public enum SortBy
{
RecentBytes,
RecentCount,
TotalBytes,
TotalCount
}
public class Stat
{
public string Name;
public long TotalCount;
public long TotalBytes;
public long RecentCount;
public long RecentBytes;
public void ResetRecent()
{
RecentCount = 0;
RecentBytes = 0;
}
public void Add(int count, int bytes)
{
TotalBytes += bytes;
TotalCount += count;
RecentBytes += bytes;
RecentCount += count;
}
}
class MessageStats
{
public readonly Dictionary<Type, Stat> MessageByType = new Dictionary<Type, Stat>();
public readonly Dictionary<ushort, Stat> RpcByHash = new Dictionary<ushort, Stat>();
public void Record(NetworkDiagnostics.MessageInfo info)
{
Type type = info.message.GetType();
if (!MessageByType.TryGetValue(type, out Stat stat))
{
stat = new Stat
{
Name = type.ToString(),
TotalCount = 0,
TotalBytes = 0,
RecentCount = 0,
RecentBytes = 0
};
MessageByType[type] = stat;
}
stat.Add(info.count, info.bytes * info.count);
if (info.message is CommandMessage cmd)
RecordRpc(cmd.functionHash, info);
else if (info.message is RpcMessage rpc)
RecordRpc(rpc.functionHash, info);
}
void RecordRpc(ushort hash, NetworkDiagnostics.MessageInfo info)
{
if (!RpcByHash.TryGetValue(hash, out Stat stat))
{
string name = "n/a";
RemoteCallDelegate rpcDelegate = RemoteProcedureCalls.GetDelegate(hash);
if (rpcDelegate != null)
name = $"{rpcDelegate.Method.DeclaringType}.{rpcDelegate.GetMethodName().Replace(RemoteProcedureCalls.InvokeRpcPrefix, "")}";
stat = new Stat
{
Name = name,
TotalCount = 0,
TotalBytes = 0,
RecentCount = 0,
RecentBytes = 0
};
RpcByHash[hash] = stat;
}
stat.Add(info.count, info.bytes * info.count);
}
public void ResetRecent()
{
foreach (Stat stat in MessageByType.Values)
stat.ResetRecent();
foreach (Stat stat in RpcByHash.Values)
stat.ResetRecent();
}
}
[Tooltip("How many seconds to accumulate 'recent' stats for, this is also the output interval")]
public float RecentDuration = 5;
public Sorter Sort = new Sorter();
public enum OutputType
{
UnityLog,
StdOut,
File
}
public OutputType Output;
[Tooltip("If Output is set to 'File', where to the path of that file")]
public string OutputFilePath = "network-stats.log";
readonly MessageStats inStats = new MessageStats();
readonly MessageStats outStats = new MessageStats();
readonly StringBuilder printBuilder = new StringBuilder();
float elapsedSinceReset;
void Start()
{
// Ordering, Awake happens before NetworkDiagnostics reset
NetworkDiagnostics.InMessageEvent += HandleMessageIn;
NetworkDiagnostics.OutMessageEvent += HandleMessageOut;
}
void OnDestroy()
{
NetworkDiagnostics.InMessageEvent -= HandleMessageIn;
NetworkDiagnostics.OutMessageEvent -= HandleMessageOut;
}
void HandleMessageOut(NetworkDiagnostics.MessageInfo info) => outStats.Record(info);
void HandleMessageIn(NetworkDiagnostics.MessageInfo info) => inStats.Record(info);
void LateUpdate()
{
elapsedSinceReset += Time.deltaTime;
if (elapsedSinceReset > RecentDuration)
{
elapsedSinceReset = 0;
Print();
inStats.ResetRecent();
outStats.ResetRecent();
}
}
void Print()
{
printBuilder.Clear();
printBuilder.AppendLine($"Stats for {DateTime.Now} ({RecentDuration:N1}s interval)");
int nameMaxLength = "OUT Message".Length;
foreach (Stat stat in inStats.MessageByType.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in outStats.MessageByType.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in inStats.RpcByHash.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in outStats.RpcByHash.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
string recentBytes = "Recent Bytes";
string recentCount = "Recent Count";
string totalBytes = "Total Bytes";
string totalCount = "Total Count";
int maxBytesLength = FormatBytes(999999).Length;
int maxCountLength = FormatCount(999999).Length;
int recentBytesPad = Mathf.Max(recentBytes.Length, maxBytesLength);
int recentCountPad = Mathf.Max(recentCount.Length, maxCountLength);
int totalBytesPad = Mathf.Max(totalBytes.Length, maxBytesLength);
int totalCountPad = Mathf.Max(totalCount.Length, maxCountLength);
string header = $"| {"IN Message".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
string sep = "".PadLeft(header.Length, '-');
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in inStats.MessageByType.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"IN RPCs".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in inStats.RpcByHash.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"OUT Message".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in outStats.MessageByType.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"OUT RPCs".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in outStats.RpcByHash.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
printBuilder.AppendLine(sep);
switch (Output)
{
case OutputType.UnityLog:
Debug.Log(printBuilder.ToString());
break;
case OutputType.StdOut:
Console.Write(printBuilder);
break;
case OutputType.File:
File.AppendAllText(OutputFilePath, printBuilder.ToString());
break;
default:
throw new ArgumentOutOfRangeException();
}
}
static string FormatBytes(long bytes)
{
const double KiB = 1024;
const double MiB = KiB * 1024;
const double GiB = MiB * 1024;
const double TiB = GiB * 1024;
if (bytes < KiB)
return $"{bytes:N0} B";
if (bytes < MiB)
return $"{bytes / KiB:N2} KiB";
if (bytes < GiB)
return $"{bytes / MiB:N2} MiB";
if (bytes < TiB)
return $"{bytes / GiB:N2} GiB";
return $"{bytes / TiB:N2} TiB";
}
string FormatCount(long count)
{
const double K = 1000;
const double M = K * 1000;
const double G = M * 1000;
const double T = G * 1000;
if (count < K)
return $"{count:N0}";
if (count < M)
return $"{count / K:N2} K";
if (count < G)
return $"{count / M:N2} M";
if (count < T)
return $"{count / G:N2} G";
return $"{count / T:N2} T";
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Mirror.RemoteCalls;
using UnityEngine;
namespace Mirror
{
public class NetworkRuntimeProfiler : MonoBehaviour
{
[Serializable]
public class Sorter : IComparer<Stat>
{
public SortBy Order;
public int Compare(Stat a, Stat b)
{
if (a == null)
return 1;
if (b == null)
return -1;
// Compare B to A for desc order
switch (Order)
{
case SortBy.RecentBytes:
return b.RecentBytes.CompareTo(a.RecentBytes);
case SortBy.RecentCount:
return b.RecentCount.CompareTo(a.RecentCount);
case SortBy.TotalBytes:
return b.TotalBytes.CompareTo(a.TotalBytes);
case SortBy.TotalCount:
return b.TotalCount.CompareTo(a.TotalCount);
default:
throw new ArgumentOutOfRangeException();
}
}
}
public enum SortBy
{
RecentBytes,
RecentCount,
TotalBytes,
TotalCount
}
public class Stat
{
public string Name;
public long TotalCount;
public long TotalBytes;
public long RecentCount;
public long RecentBytes;
public void ResetRecent()
{
RecentCount = 0;
RecentBytes = 0;
}
public void Add(int count, int bytes)
{
TotalBytes += bytes;
TotalCount += count;
RecentBytes += bytes;
RecentCount += count;
}
}
class MessageStats
{
public readonly Dictionary<Type, Stat> MessageByType = new Dictionary<Type, Stat>();
public readonly Dictionary<ushort, Stat> RpcByHash = new Dictionary<ushort, Stat>();
public void Record(NetworkDiagnostics.MessageInfo info)
{
Type type = info.message.GetType();
if (!MessageByType.TryGetValue(type, out Stat stat))
{
stat = new Stat
{
Name = type.ToString(),
TotalCount = 0,
TotalBytes = 0,
RecentCount = 0,
RecentBytes = 0
};
MessageByType[type] = stat;
}
stat.Add(info.count, info.bytes * info.count);
if (info.message is CommandMessage cmd)
RecordRpc(cmd.functionHash, info);
else if (info.message is RpcMessage rpc)
RecordRpc(rpc.functionHash, info);
}
void RecordRpc(ushort hash, NetworkDiagnostics.MessageInfo info)
{
if (!RpcByHash.TryGetValue(hash, out Stat stat))
{
string name = "n/a";
RemoteCallDelegate rpcDelegate = RemoteProcedureCalls.GetDelegate(hash);
if (rpcDelegate != null)
name = $"{rpcDelegate.Method.DeclaringType}.{rpcDelegate.GetMethodName().Replace(RemoteProcedureCalls.InvokeRpcPrefix, "")}";
stat = new Stat
{
Name = name,
TotalCount = 0,
TotalBytes = 0,
RecentCount = 0,
RecentBytes = 0
};
RpcByHash[hash] = stat;
}
stat.Add(info.count, info.bytes * info.count);
}
public void ResetRecent()
{
foreach (Stat stat in MessageByType.Values)
stat.ResetRecent();
foreach (Stat stat in RpcByHash.Values)
stat.ResetRecent();
}
}
[Tooltip("How many seconds to accumulate 'recent' stats for, this is also the output interval")]
public float RecentDuration = 5;
public Sorter Sort = new Sorter();
public enum OutputType
{
UnityLog,
StdOut,
File
}
public OutputType Output;
[Tooltip("If Output is set to 'File', where to the path of that file")]
public string OutputFilePath = "network-stats.log";
readonly MessageStats inStats = new MessageStats();
readonly MessageStats outStats = new MessageStats();
readonly StringBuilder printBuilder = new StringBuilder();
float elapsedSinceReset;
void Start()
{
// Ordering, Awake happens before NetworkDiagnostics reset
NetworkDiagnostics.InMessageEvent += HandleMessageIn;
NetworkDiagnostics.OutMessageEvent += HandleMessageOut;
}
void OnDestroy()
{
NetworkDiagnostics.InMessageEvent -= HandleMessageIn;
NetworkDiagnostics.OutMessageEvent -= HandleMessageOut;
}
void HandleMessageOut(NetworkDiagnostics.MessageInfo info) => outStats.Record(info);
void HandleMessageIn(NetworkDiagnostics.MessageInfo info) => inStats.Record(info);
void LateUpdate()
{
elapsedSinceReset += Time.deltaTime;
if (elapsedSinceReset > RecentDuration)
{
elapsedSinceReset = 0;
Print();
inStats.ResetRecent();
outStats.ResetRecent();
}
}
void Print()
{
printBuilder.Clear();
printBuilder.AppendLine($"Stats for {DateTime.Now} ({RecentDuration:N1}s interval)");
int nameMaxLength = "OUT Message".Length;
foreach (Stat stat in inStats.MessageByType.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in outStats.MessageByType.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in inStats.RpcByHash.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
foreach (Stat stat in outStats.RpcByHash.Values)
if (stat.Name.Length > nameMaxLength)
nameMaxLength = stat.Name.Length;
string recentBytes = "Recent Bytes";
string recentCount = "Recent Count";
string totalBytes = "Total Bytes";
string totalCount = "Total Count";
int maxBytesLength = FormatBytes(999999).Length;
int maxCountLength = FormatCount(999999).Length;
int recentBytesPad = Mathf.Max(recentBytes.Length, maxBytesLength);
int recentCountPad = Mathf.Max(recentCount.Length, maxCountLength);
int totalBytesPad = Mathf.Max(totalBytes.Length, maxBytesLength);
int totalCountPad = Mathf.Max(totalCount.Length, maxCountLength);
string header = $"| {"IN Message".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
string sep = "".PadLeft(header.Length, '-');
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in inStats.MessageByType.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"IN RPCs".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in inStats.RpcByHash.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"OUT Message".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in outStats.MessageByType.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
header = $"| {"OUT RPCs".PadLeft(nameMaxLength)} | {recentBytes.PadLeft(recentBytesPad)} | {recentCount.PadLeft(recentCountPad)} | {totalBytes.PadLeft(totalBytesPad)} | {totalCount.PadLeft(totalCountPad)} |";
printBuilder.AppendLine(sep);
printBuilder.AppendLine(header);
printBuilder.AppendLine(sep);
foreach (Stat stat in outStats.RpcByHash.Values.OrderBy(stat => stat, Sort))
printBuilder.AppendLine($"| {stat.Name.PadLeft(nameMaxLength)} | {FormatBytes(stat.RecentBytes).PadLeft(recentBytesPad)} | {FormatCount(stat.RecentCount).PadLeft(recentCountPad)} | {FormatBytes(stat.TotalBytes).PadLeft(totalBytesPad)} | {FormatCount(stat.TotalCount).PadLeft(totalCountPad)} |");
printBuilder.AppendLine(sep);
switch (Output)
{
case OutputType.UnityLog:
Debug.Log(printBuilder.ToString());
break;
case OutputType.StdOut:
Console.Write(printBuilder);
break;
case OutputType.File:
File.AppendAllText(OutputFilePath, printBuilder.ToString());
break;
default:
throw new ArgumentOutOfRangeException();
}
}
static string FormatBytes(long bytes)
{
const double KiB = 1024;
const double MiB = KiB * 1024;
const double GiB = MiB * 1024;
const double TiB = GiB * 1024;
if (bytes < KiB)
return $"{bytes:N0} B";
if (bytes < MiB)
return $"{bytes / KiB:N2} KiB";
if (bytes < GiB)
return $"{bytes / MiB:N2} MiB";
if (bytes < TiB)
return $"{bytes / GiB:N2} GiB";
return $"{bytes / TiB:N2} TiB";
}
string FormatCount(long count)
{
const double K = 1000;
const double M = K * 1000;
const double G = M * 1000;
const double T = G * 1000;
if (count < K)
return $"{count:N0}";
if (count < M)
return $"{count / K:N2} K";
if (count < G)
return $"{count / M:N2} M";
if (count < T)
return $"{count / G:N2} G";
return $"{count / T:N2} T";
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: ef8db82aeb77400bb9e80850e39065a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkRuntimeProfiler.cs
uploadId: 736421
fileFormatVersion: 2
guid: ef8db82aeb77400bb9e80850e39065a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/NetworkRuntimeProfiler.cs
uploadId: 736421
@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 083c6613a11cad746bb252bc7748947f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 083c6613a11cad746bb252bc7748947f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: 3c7a97355c25a2b4da731b53876f8a8b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/BandwidthGraph.prefab
uploadId: 736421
fileFormatVersion: 2
guid: 3c7a97355c25a2b4da731b53876f8a8b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/BandwidthGraph.prefab
uploadId: 736421
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: 9bdc42bca9b7109428d00fe33bdb5102
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/FPSMinMaxAvg.prefab
uploadId: 736421
fileFormatVersion: 2
guid: 9bdc42bca9b7109428d00fe33bdb5102
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/FPSMinMaxAvg.prefab
uploadId: 736421
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: e87e1847def3c1f41b19b7df4f0920b3
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/GraphCanvas.prefab
uploadId: 736421
fileFormatVersion: 2
guid: e87e1847def3c1f41b19b7df4f0920b3
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/GraphCanvas.prefab
uploadId: 736421
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: a4ee3092d7c7f4a38a70b11014175ebd
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/NetworkGraph.prefab
uploadId: 736421
fileFormatVersion: 2
guid: a4ee3092d7c7f4a38a70b11014175ebd
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/NetworkGraph.prefab
uploadId: 736421
File diff suppressed because it is too large Load Diff
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: ed3b4e27086dcc64b8c6605011a321e2
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/PingGraph.prefab
uploadId: 736421
fileFormatVersion: 2
guid: ed3b4e27086dcc64b8c6605011a321e2
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/Prefabs/PingGraph.prefab
uploadId: 736421
@@ -1,88 +1,88 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: StackedGraph
m_Shader: {fileID: 4800000, guid: b5b24284f35f4992bcd4cc43919267d7, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _CategoryCount: 0
- _ColorMask: 15
- _Cutoff: 0.5
- _DataStart: 0
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _MaxValue: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _Width: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: StackedGraph
m_Shader: {fileID: 4800000, guid: b5b24284f35f4992bcd4cc43919267d7, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _CategoryCount: 0
- _ColorMask: 15
- _Cutoff: 0.5
- _DataStart: 0
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _MaxValue: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _Width: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
@@ -1,15 +1,15 @@
fileFormatVersion: 2
guid: 14fba9d19cfe7f346bfb595965558722
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/StackedGraph.mat
uploadId: 736421
fileFormatVersion: 2
guid: 14fba9d19cfe7f346bfb595965558722
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/StackedGraph.mat
uploadId: 736421
@@ -1,15 +1,15 @@
using UnityEngine;
namespace Mirror
{
public class ToggleHotkey : MonoBehaviour
{
public KeyCode Key = KeyCode.F10;
public GameObject ToToggle;
void Update()
{
if (Input.GetKeyDown(Key))
ToToggle.SetActive(!ToToggle.activeSelf);
}
}
}
using UnityEngine;
namespace Mirror
{
public class ToggleHotkey : MonoBehaviour
{
public KeyCode Key = KeyCode.F10;
public GameObject ToToggle;
void Update()
{
if (Input.GetKeyDown(Key))
ToToggle.SetActive(!ToToggle.activeSelf);
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: a27b133d890c41828d3b01ffa12fe440
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/ToggleHotkey.cs
uploadId: 736421
fileFormatVersion: 2
guid: a27b133d890c41828d3b01ffa12fe440
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129321
packageName: Mirror
packageVersion: 96.0.1
assetPath: Assets/Mirror/Components/Profiling/ToggleHotkey.cs
uploadId: 736421