Files
bansonic_beta_main/Assets/playerInfoDisplay/uRader/URadarChartController.cs
T

498 lines
16 KiB
C#

using System.Collections.Generic;
using EasyChart;
using EasyChart.UGUI;
using UnityEngine;
public class URadarChartController : MonoBehaviour
{
[Header("Chart")]
public UGUIChartBridge chartBridge;
public bool rebuildOnEnable = true;
public bool showReferenceSeries = false;
public int enforcedSortOrder = 0;
[Header("Axis Count")]
[Min(3)] public int axisCount = 6;
[Header("Series Names")]
public string mainSeriesName = "Player";
public string referenceSeriesName = "Reference";
[Header("Axes")]
public List<URadarAxisEntry> axes = new List<URadarAxisEntry>
{
new URadarAxisEntry { label = "A", value = 72f, referenceValue = 60f },
new URadarAxisEntry { label = "B", value = 55f, referenceValue = 60f },
new URadarAxisEntry { label = "C", value = 68f, referenceValue = 60f },
new URadarAxisEntry { label = "D", value = 49f, referenceValue = 60f },
new URadarAxisEntry { label = "E", value = 80f, referenceValue = 60f },
new URadarAxisEntry { label = "F", value = 61f, referenceValue = 60f }
};
[Header("Range")]
public float minValue = 0f;
public float maxValue = 100f;
public int splitCount = 5;
[Header("Grid")]
public bool overrideGridStyle = false;
public Color gridLineColor = new Color32(255, 255, 255, 180);
public Color outerGridLineColor = Color.white;
public float gridLineWidth = 2f;
[Header("Labels")]
public bool overrideLabelStyle = false;
public bool overrideLabelFont = false;
public Font axisLabelFont;
public int axisLabelFontSize = 18;
public Color axisLabelColor = Color.white;
public Vector2 axisLabelOffset = Vector2.zero;
[Header("Tooltip")]
public bool overrideTooltipStyle = false;
public bool overrideTooltipFont = false;
public Font tooltipFont;
public int tooltipFontSize = 18;
public Color tooltipTextColor = Color.white;
public Color tooltipBackgroundColor = new Color(0f, 0f, 0f, 0.85f);
public Color tooltipBorderColor = new Color(1f, 1f, 1f, 0f);
[Min(0f)] public float tooltipBorderWidth = 0f;
[Min(0f)] public float tooltipCornerRadius = 4f;
public Vector4 tooltipPadding = new Vector4(8f, 8f, 4f, 4f);
[Header("Style")]
public bool overrideSeriesStyle = true;
public Color mainStrokeColor = new Color32(82, 126, 255, 255);
public Color mainFillColor = new Color(82f / 255f, 126f / 255f, 255f / 255f, 0.28f);
public Color mainPointColor = Color.white;
public Color referenceStrokeColor = new Color32(72, 229, 229, 255);
public Color referenceFillColor = new Color(72f / 255f, 229f / 255f, 229f / 255f, 0.22f);
public Color referencePointColor = Color.white;
public float radarPlotPadding = 8f;
[Min(0f)] public float radarInnerRadius = 0f;
[Min(0f)] public float radarLabelRadialOffset = 0f;
private ChartProfile sourceProfile;
private ChartProfile runtimeProfile;
private ChartTheme runtimeTheme;
private bool rebuildQueued;
private void Awake()
{
showReferenceSeries = false;
NormalizeAxes();
QueueRebuild();
}
private void OnEnable()
{
showReferenceSeries = false;
NormalizeAxes();
if (rebuildOnEnable)
{
QueueRebuild();
}
}
private void LateUpdate()
{
if (rebuildQueued)
{
TryRebuild();
}
}
private void OnValidate()
{
showReferenceSeries = false;
NormalizeAxes();
axisLabelFontSize = Mathf.Max(1, axisLabelFontSize);
tooltipFontSize = Mathf.Max(1, tooltipFontSize);
gridLineWidth = Mathf.Max(0.1f, gridLineWidth);
radarInnerRadius = Mathf.Max(0f, radarInnerRadius);
radarLabelRadialOffset = Mathf.Max(0f, radarLabelRadialOffset);
tooltipBorderWidth = Mathf.Max(0f, tooltipBorderWidth);
tooltipCornerRadius = Mathf.Max(0f, tooltipCornerRadius);
axisCount = Mathf.Max(3, axisCount);
QueueRebuild();
}
private void OnDestroy()
{
if (runtimeProfile != null)
{
DestroyImmediate(runtimeProfile);
runtimeProfile = null;
}
if (runtimeTheme != null)
{
DestroyImmediate(runtimeTheme);
runtimeTheme = null;
}
}
public void QueueRebuild()
{
rebuildQueued = true;
}
[ContextMenu("Rebuild Radar Chart")]
public void RebuildNow()
{
QueueRebuild();
TryRebuild();
}
public void SetAxisLabel(int index, string label)
{
if (!TryGetAxis(index, out URadarAxisEntry axis))
{
return;
}
axis.label = string.IsNullOrWhiteSpace(label) ? $"Axis {index + 1}" : label.Trim();
QueueRebuild();
}
public void SetAxisValue(int index, float value)
{
if (!TryGetAxis(index, out URadarAxisEntry axis))
{
return;
}
axis.value = Mathf.Clamp(value, minValue, maxValue);
QueueRebuild();
}
public void SetReferenceAxisValue(int index, float value)
{
if (!TryGetAxis(index, out URadarAxisEntry axis))
{
return;
}
axis.referenceValue = Mathf.Clamp(value, minValue, maxValue);
QueueRebuild();
}
public void SetAxisData(int index, string label, float value, float referenceValueToSet)
{
NormalizeAxes();
if (index < 0 || index >= axes.Count)
{
return;
}
URadarAxisEntry axis = axes[index];
if (axis == null)
{
axis = new URadarAxisEntry();
axes[index] = axis;
}
axis.label = string.IsNullOrWhiteSpace(label) ? $"Axis {index + 1}" : label.Trim();
axis.value = Mathf.Clamp(value, minValue, maxValue);
axis.referenceValue = Mathf.Clamp(referenceValueToSet, minValue, maxValue);
QueueRebuild();
}
public void NormalizeAxesForExternalUse()
{
NormalizeAxes();
}
private bool TryGetAxis(int index, out URadarAxisEntry axis)
{
NormalizeAxes();
if (index < 0 || index >= axes.Count)
{
axis = null;
return false;
}
axis = axes[index];
return axis != null;
}
private void TryRebuild()
{
if (chartBridge == null || chartBridge.Profile == null)
{
return;
}
if (sourceProfile == null)
{
sourceProfile = chartBridge.Profile;
}
if (sourceProfile == null)
{
return;
}
EnsureRuntimeProfile();
EnsureBridgePriority();
ConfigureRuntimeProfile();
chartBridge.Refresh();
ApplyRuntimeTheme();
rebuildQueued = false;
}
private void EnsureRuntimeProfile()
{
if (runtimeProfile != null)
{
if (!ReferenceEquals(chartBridge.Profile, runtimeProfile))
{
chartBridge.Profile = runtimeProfile;
}
return;
}
runtimeProfile = Instantiate(sourceProfile);
runtimeProfile.name = sourceProfile.name + "_URadar_Runtime";
runtimeProfile.hideFlags = HideFlags.DontSave;
chartBridge.Profile = runtimeProfile;
}
private void EnsureBridgePriority()
{
if (chartBridge != null && chartBridge.SortOrder < enforcedSortOrder)
{
chartBridge.SortOrder = enforcedSortOrder;
}
}
private void ConfigureRuntimeProfile()
{
NormalizeAxes();
runtimeProfile.coordinateSystem = CoordinateSystemType.Polar2D;
runtimeProfile.EnsureRuntimeData();
runtimeProfile.polarAxes.angleAxis.labels = BuildLabels();
runtimeProfile.polarAxes.angleAxis.visible = true;
runtimeProfile.polarAxes.angleAxis.showLabels = true;
if (runtimeProfile.polarAxes.angleAxis.labelStyle == null)
{
runtimeProfile.polarAxes.angleAxis.labelStyle = new LabelStyleSettings();
}
runtimeProfile.polarAxes.angleAxis.labelStyle.enabled = true;
runtimeProfile.polarAxes.radiusAxis.visible = true;
runtimeProfile.polarAxes.radiusAxis.autoRangeMin = false;
runtimeProfile.polarAxes.radiusAxis.autoRangeMax = false;
runtimeProfile.polarAxes.radiusAxis.minValue = minValue;
runtimeProfile.polarAxes.radiusAxis.maxValue = Mathf.Max(minValue + 1f, maxValue);
runtimeProfile.polarAxes.radiusAxis.splitCount = Mathf.Max(2, splitCount);
if (runtimeProfile.polarAxes.radiusAxis.labelStyle == null)
{
runtimeProfile.polarAxes.radiusAxis.labelStyle = new LabelStyleSettings();
}
runtimeProfile.polarAxes.radiusAxis.labelStyle.enabled = runtimeProfile.polarAxes.radiusAxis.showLabels;
if (overrideGridStyle)
{
runtimeProfile.polarAxes.angleAxis.color = gridLineColor;
runtimeProfile.polarAxes.angleAxis.width = gridLineWidth;
runtimeProfile.polarAxes.radiusAxis.color = gridLineColor;
runtimeProfile.polarAxes.radiusAxis.edgeColor = outerGridLineColor;
runtimeProfile.polarAxes.radiusAxis.width = gridLineWidth;
}
if (overrideLabelStyle)
{
runtimeProfile.polarAxes.angleAxis.labelColor = axisLabelColor;
runtimeProfile.polarAxes.angleAxis.fontSize = axisLabelFontSize;
runtimeProfile.polarAxes.angleAxis.labelOffset = axisLabelOffset;
runtimeProfile.polarAxes.angleAxis.labelStyle.fontSize = axisLabelFontSize;
runtimeProfile.polarAxes.angleAxis.labelStyle.color = axisLabelColor;
runtimeProfile.polarAxes.angleAxis.labelStyle.offset = axisLabelOffset;
runtimeProfile.polarAxes.radiusAxis.labelColor = axisLabelColor;
runtimeProfile.polarAxes.radiusAxis.fontSize = axisLabelFontSize;
runtimeProfile.polarAxes.radiusAxis.labelStyle.fontSize = axisLabelFontSize;
runtimeProfile.polarAxes.radiusAxis.labelStyle.color = axisLabelColor;
}
if (runtimeProfile.series == null)
{
runtimeProfile.series = new List<Serie>();
}
int targetSeriesCount = 1;
while (runtimeProfile.series.Count < targetSeriesCount)
{
runtimeProfile.series.Add(new Serie());
}
while (runtimeProfile.series.Count > targetSeriesCount)
{
runtimeProfile.series.RemoveAt(runtimeProfile.series.Count - 1);
}
ConfigureSeries(runtimeProfile.series[0], mainSeriesName, true);
runtimeProfile.EnsureRuntimeData();
}
private void ApplyRuntimeTheme()
{
if (chartBridge == null || chartBridge.ChartElement == null)
{
return;
}
bool useTooltipStyle = overrideTooltipStyle;
bool useTooltipFont = overrideTooltipFont && tooltipFont != null;
bool useLabelFont = overrideLabelFont && axisLabelFont != null;
if (!useLabelFont && !useTooltipFont && !useTooltipStyle)
{
chartBridge.ChartElement.Theme = null;
return;
}
if (runtimeTheme == null)
{
runtimeTheme = ScriptableObject.CreateInstance<ChartTheme>();
runtimeTheme.name = "URadar_RuntimeTheme";
runtimeTheme.hideFlags = HideFlags.DontSave;
}
runtimeTheme.primaryFont = useLabelFont ? axisLabelFont : null;
runtimeTheme.axisFontSize = useLabelFont ? axisLabelFontSize : -1f;
runtimeTheme.tooltipFont = useTooltipFont ? tooltipFont : null;
runtimeTheme.tooltipFontSize = (useTooltipFont || useTooltipStyle) ? tooltipFontSize : -1f;
runtimeTheme.tooltipTextColor = useTooltipStyle ? tooltipTextColor : Color.white;
runtimeTheme.tooltipBackgroundColor = useTooltipStyle ? tooltipBackgroundColor : new Color(0f, 0f, 0f, 0.8f);
runtimeTheme.tooltipBorderColor = useTooltipStyle ? tooltipBorderColor : new Color(0f, 0f, 0f, 0f);
runtimeTheme.tooltipBorderWidth = useTooltipStyle ? tooltipBorderWidth : 0f;
runtimeTheme.tooltipCornerRadius = useTooltipStyle ? tooltipCornerRadius : 4f;
runtimeTheme.tooltipPadding = useTooltipStyle ? tooltipPadding : new Vector4(8f, 8f, 4f, 4f);
// Force ChartElement.Theme setter to re-apply tooltip visuals even when reusing the same runtime theme instance.
chartBridge.ChartElement.Theme = null;
chartBridge.ChartElement.Theme = runtimeTheme;
}
private void ConfigureSeries(Serie serie, string serieName, bool isMainSeries)
{
if (serie == null)
{
return;
}
serie.name = string.IsNullOrWhiteSpace(serieName) ? (isMainSeries ? "Player" : "Reference") : serieName.Trim();
serie.visible = true;
if (serie.type != SerieType.Radar)
{
serie.SetType(SerieType.Radar);
}
if (!(serie.settings is RadarSettings radarSettings))
{
radarSettings = new RadarSettings();
serie.settings = radarSettings;
}
radarSettings.radar.innerRadius = radarInnerRadius;
radarSettings.radar.outerRadius = 0f;
radarSettings.radar.plot.padding = radarPlotPadding;
radarSettings.radar.plot.labelRadialOffset = radarLabelRadialOffset;
radarSettings.area.show = true;
radarSettings.point.show = true;
if (overrideSeriesStyle)
{
radarSettings.stroke.color = isMainSeries ? mainStrokeColor : referenceStrokeColor;
radarSettings.stroke.width = isMainSeries ? 2.5f : 2f;
radarSettings.area.textureFill.color = isMainSeries ? mainFillColor : referenceFillColor;
radarSettings.point.textureFill.color = isMainSeries ? mainPointColor : referencePointColor;
radarSettings.point.size = isMainSeries ? 8f : 7f;
}
if (serie.labelSettings != null)
{
serie.labelSettings.enabled = false;
}
if (serie.seriesData == null)
{
serie.seriesData = new List<SeriesData>();
}
else
{
serie.seriesData.Clear();
}
for (int i = 0; i < axisCount; i++)
{
URadarAxisEntry axis = axes[i];
float value = isMainSeries ? axis.value : axis.referenceValue;
serie.seriesData.Add(new SeriesData
{
id = (isMainSeries ? "main_" : "ref_") + i,
name = axis.label,
x = i,
value = Mathf.Clamp(value, minValue, maxValue)
});
}
}
private List<string> BuildLabels()
{
List<string> labels = new List<string>(axisCount);
for (int i = 0; i < axisCount; i++)
{
string label = axes[i] != null ? axes[i].label : null;
labels.Add(string.IsNullOrWhiteSpace(label) ? $"Axis {i + 1}" : label.Trim());
}
return labels;
}
private void NormalizeAxes()
{
if (axes == null)
{
axes = new List<URadarAxisEntry>();
}
axisCount = Mathf.Max(3, axisCount);
while (axes.Count < axisCount)
{
axes.Add(new URadarAxisEntry
{
label = $"Axis {axes.Count + 1}",
value = 50f,
referenceValue = 60f
});
}
if (axes.Count > axisCount)
{
axes.RemoveRange(axisCount, axes.Count - axisCount);
}
for (int i = 0; i < axes.Count; i++)
{
if (axes[i] == null)
{
axes[i] = new URadarAxisEntry
{
label = $"Axis {i + 1}",
value = 50f,
referenceValue = 60f
};
}
}
}
}