Files
2026-07-30 23:15:58 +08:00

175 lines
5.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using EasyChart;
using System.Collections.Generic;
/// <summary>
/// 判定偏移直方图:用 EasyChart 可视化判定偏移分布。
/// 从 ScoreManager.OffsetSamples 读取数据并绘制直方图。
/// 供后续快速接入(需你指定在何处显示此组件)。
/// </summary>
[RequireComponent(typeof(ChartElement))]
public class JudgeOffsetHistogram : MonoBehaviour
{
[Header("数据源")]
[SerializeField] private ScoreManager scoreManager;
[Header("直方图配置")]
[SerializeField] private int binCount = 20; // 分箱数(横轴分段)
[SerializeField] private float rangeMin = -200f; // ms
[SerializeField] private float rangeMax = 200f; // ms
[SerializeField] private Color barColor = new Color(0.2f, 0.6f, 1f, 0.8f);
[Header("标签")]
[SerializeField] private string chartTitle = "Judge Offset Distribution";
[SerializeField] private string xAxisLabel = "Offset (ms)";
[SerializeField] private string yAxisLabel = "Count";
private ChartElement chartElement;
private ChartData chartData;
private void Awake()
{
chartElement = GetComponent<ChartElement>();
if (chartElement == null)
{
Debug.LogError("[JudgeOffsetHistogram] ChartElement component not found!");
return;
}
// 自动查找 ScoreManager(如果未手动赋值)
if (scoreManager == null)
{
scoreManager = FindObjectOfType<ScoreManager>();
}
}
/// <summary>
/// 刷新直方图:从 ScoreManager.offsetSamples 读取数据并绘制。
/// 在结算页显示时调用。
/// </summary>
public void RefreshHistogram()
{
if (scoreManager == null)
{
Debug.LogWarning("[JudgeOffsetHistogram] ScoreManager not assigned.");
return;
}
// 读取偏移样本(ms
IReadOnlyList<float> samples = scoreManager.OffsetSamples;
if (samples == null || samples.Count == 0)
{
Debug.LogWarning("[JudgeOffsetHistogram] No offset samples available.");
return;
}
// 分箱统计
int[] bins = new int[binCount];
float binWidth = (rangeMax - rangeMin) / binCount;
foreach (float offset in samples)
{
if (offset < rangeMin || offset >= rangeMax) continue; // 超出范围忽略
int binIndex = Mathf.FloorToInt((offset - rangeMin) / binWidth);
binIndex = Mathf.Clamp(binIndex, 0, binCount - 1);
bins[binIndex]++;
}
// 构建 EasyChart ChartData
BuildChartData(bins, binWidth);
// 应用到 ChartElement
if (chartElement != null && chartData != null)
{
chartElement.SetData(chartData);
Debug.Log($"[JudgeOffsetHistogram] Refreshed with {samples.Count} samples, {binCount} bins.");
}
}
private void BuildChartData(int[] bins, float binWidth)
{
chartData = new ChartData();
// 配置坐标系为笛卡尔2D
chartData.CoordinateSystem = CoordinateSystemType.Cartesian2D;
chartData.XAxisId = AxisId.XBottom;
chartData.YAxisId = AxisId.YLeft;
// X 轴配置(类目轴,显示偏移区间)
var xAxis = new AxisConfig
{
id = AxisId.XBottom,
axisType = AxisType.Category,
labels = new List<string>()
};
for (int i = 0; i < binCount; i++)
{
float binCenter = rangeMin + (i + 0.5f) * binWidth;
xAxis.labels.Add($"{binCenter:F0}");
}
// Y 轴配置(数值轴,显示计数)
var yAxis = new AxisConfig
{
id = AxisId.YLeft,
axisType = AxisType.Value,
minValue = 0f,
autoRangeMin = true,
autoRangeMax = true
};
chartData.Axes = new List<AxisConfig> { xAxis, yAxis };
// 创建柱状图系列
var serie = new Serie
{
name = chartTitle,
type = SerieType.Bar,
seriesData = new List<SeriesData>()
};
// 填充数据点
for (int i = 0; i < binCount; i++)
{
serie.seriesData.Add(new SeriesData
{
x = i,
value = bins[i]
});
}
// 配置柱状图样式(可选)
var barSettings = new BarSettings();
if (barSettings.textureFill == null)
{
barSettings.textureFill = new TextureFillSettings { color = barColor };
}
else
{
barSettings.textureFill.color = barColor;
}
serie.settings = barSettings;
chartData.Series = new List<Serie> { serie };
}
/// <summary>
/// 清空直方图。
/// </summary>
public void ClearHistogram()
{
if (chartElement != null)
{
chartElement.SetData(null);
}
}
// 供 Inspector 测试用的按钮方法
[ContextMenu("Test Refresh Histogram")]
private void TestRefresh()
{
RefreshHistogram();
}
}