UI update 02
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
public class UIRadarGraphic : MaskableGraphic
|
||||
{
|
||||
private const float MainStrokeWidth = 2.5f;
|
||||
private const float ReferenceStrokeWidth = 2f;
|
||||
private const float MainPointSize = 8f;
|
||||
private const float ReferencePointSize = 7f;
|
||||
|
||||
private readonly List<URadarAxisEntry> axisEntries = new List<URadarAxisEntry>();
|
||||
|
||||
private float minValue;
|
||||
private float maxValue = 100f;
|
||||
private int splitCount = 5;
|
||||
private bool showReferenceSeries;
|
||||
private Color gridLineColor = new Color32(255, 255, 255, 180);
|
||||
private Color outerGridLineColor = Color.white;
|
||||
private float gridLineWidth = 2f;
|
||||
private Color mainStrokeColor = new Color32(82, 126, 255, 255);
|
||||
private Color mainFillColor = new Color(82f / 255f, 126f / 255f, 255f / 255f, 0.28f);
|
||||
private Color mainPointColor = Color.white;
|
||||
private Color referenceStrokeColor = new Color32(72, 229, 229, 255);
|
||||
private Color referenceFillColor = new Color(72f / 255f, 229f / 255f, 229f / 255f, 0.22f);
|
||||
private Color referencePointColor = Color.white;
|
||||
private float radarPlotPadding = 8f;
|
||||
private float radarInnerRadius;
|
||||
private float radarLabelRadialOffset;
|
||||
|
||||
public void SetData(
|
||||
List<URadarAxisEntry> sourceAxes,
|
||||
float sourceMinValue,
|
||||
float sourceMaxValue,
|
||||
int sourceSplitCount,
|
||||
bool sourceShowReferenceSeries,
|
||||
Color sourceGridLineColor,
|
||||
Color sourceOuterGridLineColor,
|
||||
float sourceGridLineWidth,
|
||||
Color sourceMainStrokeColor,
|
||||
Color sourceMainFillColor,
|
||||
Color sourceMainPointColor,
|
||||
Color sourceReferenceStrokeColor,
|
||||
Color sourceReferenceFillColor,
|
||||
Color sourceReferencePointColor,
|
||||
float sourceRadarPlotPadding,
|
||||
float sourceRadarInnerRadius,
|
||||
float sourceRadarLabelRadialOffset)
|
||||
{
|
||||
axisEntries.Clear();
|
||||
if (sourceAxes != null)
|
||||
{
|
||||
for (int i = 0; i < sourceAxes.Count; i++)
|
||||
{
|
||||
URadarAxisEntry source = sourceAxes[i];
|
||||
if (source == null)
|
||||
{
|
||||
axisEntries.Add(new URadarAxisEntry());
|
||||
continue;
|
||||
}
|
||||
|
||||
axisEntries.Add(new URadarAxisEntry
|
||||
{
|
||||
label = source.label,
|
||||
value = source.value,
|
||||
referenceValue = source.referenceValue
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
minValue = sourceMinValue;
|
||||
maxValue = Mathf.Max(sourceMinValue + 0.0001f, sourceMaxValue);
|
||||
splitCount = Mathf.Max(2, sourceSplitCount);
|
||||
showReferenceSeries = sourceShowReferenceSeries;
|
||||
gridLineColor = sourceGridLineColor;
|
||||
outerGridLineColor = sourceOuterGridLineColor;
|
||||
gridLineWidth = Mathf.Max(0.1f, sourceGridLineWidth);
|
||||
mainStrokeColor = sourceMainStrokeColor;
|
||||
mainFillColor = sourceMainFillColor;
|
||||
mainPointColor = sourceMainPointColor;
|
||||
referenceStrokeColor = sourceReferenceStrokeColor;
|
||||
referenceFillColor = sourceReferenceFillColor;
|
||||
referencePointColor = sourceReferencePointColor;
|
||||
radarPlotPadding = Mathf.Max(0f, sourceRadarPlotPadding);
|
||||
radarInnerRadius = Mathf.Max(0f, sourceRadarInnerRadius);
|
||||
radarLabelRadialOffset = sourceRadarLabelRadialOffset;
|
||||
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
vh.Clear();
|
||||
|
||||
if (axisEntries.Count < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rect = GetPixelAdjustedRect();
|
||||
Vector2 center = rect.center;
|
||||
float maxRadius = Mathf.Max(0f, Mathf.Min(rect.width, rect.height) * 0.5f - radarPlotPadding - Mathf.Max(MainPointSize, ReferencePointSize));
|
||||
float innerRadius = Mathf.Clamp(radarInnerRadius, 0f, maxRadius * 0.8f);
|
||||
|
||||
DrawGrid(vh, center, innerRadius, maxRadius);
|
||||
|
||||
List<Vector2> mainPoints = BuildSeriesPoints(center, innerRadius, maxRadius, false);
|
||||
if (showReferenceSeries)
|
||||
{
|
||||
List<Vector2> referencePoints = BuildSeriesPoints(center, innerRadius, maxRadius, true);
|
||||
DrawFilledPolygon(vh, center, referencePoints, referenceFillColor);
|
||||
DrawPolyline(vh, referencePoints, true, ReferenceStrokeWidth, referenceStrokeColor);
|
||||
DrawPointMarkers(vh, referencePoints, ReferencePointSize, referencePointColor);
|
||||
}
|
||||
|
||||
DrawFilledPolygon(vh, center, mainPoints, mainFillColor);
|
||||
DrawPolyline(vh, mainPoints, true, MainStrokeWidth, mainStrokeColor);
|
||||
DrawPointMarkers(vh, mainPoints, MainPointSize, mainPointColor);
|
||||
}
|
||||
|
||||
private void DrawGrid(VertexHelper vh, Vector2 center, float innerRadius, float maxRadius)
|
||||
{
|
||||
int axisCount = axisEntries.Count;
|
||||
for (int ring = 1; ring <= splitCount; ring++)
|
||||
{
|
||||
float t = ring / (float)splitCount;
|
||||
float radius = Mathf.Lerp(innerRadius, maxRadius, t);
|
||||
List<Vector2> ringPoints = new List<Vector2>(axisCount);
|
||||
for (int i = 0; i < axisCount; i++)
|
||||
{
|
||||
ringPoints.Add(GetAxisPoint(center, radius, i, axisCount));
|
||||
}
|
||||
|
||||
DrawPolyline(vh, ringPoints, true, gridLineWidth, ring == splitCount ? outerGridLineColor : gridLineColor);
|
||||
}
|
||||
|
||||
for (int i = 0; i < axisCount; i++)
|
||||
{
|
||||
Vector2 start = GetAxisPoint(center, innerRadius, i, axisCount);
|
||||
Vector2 end = GetAxisPoint(center, maxRadius, i, axisCount);
|
||||
DrawLine(vh, start, end, gridLineWidth, gridLineColor);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Vector2> BuildSeriesPoints(Vector2 center, float innerRadius, float maxRadius, bool useReferenceValue)
|
||||
{
|
||||
int axisCount = axisEntries.Count;
|
||||
List<Vector2> points = new List<Vector2>(axisCount);
|
||||
|
||||
for (int i = 0; i < axisCount; i++)
|
||||
{
|
||||
URadarAxisEntry entry = axisEntries[i];
|
||||
float value = useReferenceValue ? entry.referenceValue : entry.value;
|
||||
float normalized = Mathf.InverseLerp(minValue, maxValue, Mathf.Clamp(value, minValue, maxValue));
|
||||
float radius = Mathf.Lerp(innerRadius, maxRadius, normalized);
|
||||
points.Add(GetAxisPoint(center, radius, i, axisCount));
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
private static Vector2 GetAxisPoint(Vector2 center, float radius, int axisIndex, int axisCount)
|
||||
{
|
||||
float angle = Mathf.PI * 0.5f - (Mathf.PI * 2f / axisCount) * axisIndex;
|
||||
return center + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
|
||||
}
|
||||
|
||||
private static void DrawFilledPolygon(VertexHelper vh, Vector2 center, List<Vector2> points, Color color)
|
||||
{
|
||||
if (points == null || points.Count < 3 || color.a <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int startIndex = vh.currentVertCount;
|
||||
UIVertex centerVertex = UIVertex.simpleVert;
|
||||
centerVertex.color = color;
|
||||
centerVertex.position = center;
|
||||
vh.AddVert(centerVertex);
|
||||
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
UIVertex vertex = UIVertex.simpleVert;
|
||||
vertex.color = color;
|
||||
vertex.position = points[i];
|
||||
vh.AddVert(vertex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
int current = startIndex + 1 + i;
|
||||
int next = startIndex + 1 + ((i + 1) % points.Count);
|
||||
vh.AddTriangle(startIndex, current, next);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawPolyline(VertexHelper vh, List<Vector2> points, bool closed, float thickness, Color color)
|
||||
{
|
||||
if (points == null || points.Count < 2 || color.a <= 0f || thickness <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < points.Count - 1; i++)
|
||||
{
|
||||
DrawLine(vh, points[i], points[i + 1], thickness, color);
|
||||
}
|
||||
|
||||
if (closed)
|
||||
{
|
||||
DrawLine(vh, points[points.Count - 1], points[0], thickness, color);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawLine(VertexHelper vh, Vector2 start, Vector2 end, float thickness, Color color)
|
||||
{
|
||||
Vector2 delta = end - start;
|
||||
if (delta.sqrMagnitude <= 0.0001f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 normal = new Vector2(-delta.y, delta.x).normalized * (thickness * 0.5f);
|
||||
int index = vh.currentVertCount;
|
||||
|
||||
UIVertex vertex = UIVertex.simpleVert;
|
||||
vertex.color = color;
|
||||
|
||||
vertex.position = start - normal;
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = start + normal;
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = end + normal;
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = end - normal;
|
||||
vh.AddVert(vertex);
|
||||
|
||||
vh.AddTriangle(index, index + 1, index + 2);
|
||||
vh.AddTriangle(index, index + 2, index + 3);
|
||||
}
|
||||
|
||||
private static void DrawPointMarkers(VertexHelper vh, List<Vector2> points, float size, Color color)
|
||||
{
|
||||
if (points == null || color.a <= 0f || size <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float half = size * 0.5f;
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
DrawQuad(vh, points[i], new Vector2(half, half), color);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawQuad(VertexHelper vh, Vector2 center, Vector2 halfSize, Color color)
|
||||
{
|
||||
int index = vh.currentVertCount;
|
||||
UIVertex vertex = UIVertex.simpleVert;
|
||||
vertex.color = color;
|
||||
|
||||
vertex.position = new Vector2(center.x - halfSize.x, center.y - halfSize.y);
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = new Vector2(center.x - halfSize.x, center.y + halfSize.y);
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = new Vector2(center.x + halfSize.x, center.y + halfSize.y);
|
||||
vh.AddVert(vertex);
|
||||
vertex.position = new Vector2(center.x + halfSize.x, center.y - halfSize.y);
|
||||
vh.AddVert(vertex);
|
||||
|
||||
vh.AddTriangle(index, index + 1, index + 2);
|
||||
vh.AddTriangle(index, index + 2, index + 3);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user