# three way radar chart

I am trying to make a radar chart that uses three values. The radar chart will part of my games HUD but I cant figure out the best way to do it. I am not asking for the maths or anything I should be able to figure that out. More just the best way to do it and make it look nice.
I have been looking into use the draw command but I don’t think it will give quite the look I am looking for.

Would be very easy with a mesh, I’ll look into any methods that are UI savvy…

Wow that would be great! Never even considered using a mesh. Any more information and or help would be greatly appreciated.

I have been looking at the load pixel command and considering using that.

The only issue is this is the example script from Unities site. I understand that GL.Vertex is what alters the image. (Correct me if I am wrong) However when ever I change any of the numbers the triangle becomes invisible or at least doesn’t render. I am trying to make it render at the bottom left corner and making it fairly small. Any help would be great, in the mean time I am still going to study the issue myself.

If anybody is still/will be looking for a way to do this, I just hacked up an incredibly reliable solution to this problem. Since I didn’t really wanna figure out the maths necessary to draw one in pixels, I decided that generating a mesh would be the best way to go. Just designate how many Axis you need and it will generate them. I said this is kind of a hack (as it uses a mix of pre-made gameobjects and generated mesh), but it’s pretty much flawless. So, here’s how I did it:

Step 1: Create an “Axis” Object that represents a single axes of the chart. For this to work you’ll need to make sure the Game Object’s pivot its at the base. Within the Axis should be an empty game onject for the top of the graph, and a “marker” (a cube or sphere should work fine) that represents the place of the data value on that axis. For ease of access, I made a script that would attach to an axis to store the top of the axis and “marker”.

Step 2: Create a script that will automatically set up the chart for you given data. This takes a bit of knowledge on how Meshes work in unity. I was able to accomplish what was necessary after going through the first part of this neat little demo:

Since it would take a little while to explain what I did and how I did it, I think I’ll just post the script and leave the rest to you guys. Here’s the code (don’t be intimidated by its size, I’m a bit of a noob):

``````using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class RadarGraph : MonoBehaviour {

public Transform axisBar;	//Axis of Radar Graph
public int axisNum;			//Number of Axis in graph
public Material mater;		//Radar Graph material

private float angleNum;		//Angle at which each axis is rotated
private Dictionary<string, float> data = new Dictionary<string, float>(); //Stores data to be displayed
private List<Vector3> points = new List<Vector3>();		//Stores vertex positions to generate mesh

// Use this for initialization
void Start () {
float rotoAngle = 0;	//Angle of rotation for current Axis being added;
angleNum = 360/axisNum;

//Function for acquiring data. Just pulls Random values, atm.
getData();

//Adds origin for center of Graph

//Adds in and sets values of Axis
for( int i = 0; i < axisNum; i++ )
{
//Instantiates Axis
Transform axis = Instantiate(axisBar, transform.position, Quaternion.identity) as Transform;

//Grabs current data Item
var item = data.ElementAt(i);

//Accesses Axis script and sets Marker's position locally in accordance to its value
////Its position is determined by where the data falls between the lowest and highest possible data points (as a percentage of 100).
GraphAxis gAxis = axis.gameObject.GetComponent<GraphAxis>();
Vector3 pos = gAxis.marker.localPosition;
pos.y = (gAxis.top.position.y - gAxis.transform.position.y) * (item.Value/100);
gAxis.marker.localPosition = pos;

//Temp vector3 for multiple purposes
Vector3 temp = axis.eulerAngles;

//Assign Axis angle
temp.z = rotoAngle;
axis.eulerAngles = temp;

//Straitens out Text Labels (3D GUI in this instance) if Axis have them (Optional)
temp = gAxis.text.transform.eulerAngles;
temp.z = 0;
gAxis.text.transform.eulerAngles = temp;

//Adjusts Text position as to not obstruct data (Optional)
TextMesh text = gAxis.text;
temp = text.transform.position;
if(rotoAngle < 180  rotoAngle != 0)
temp.x -= ((text.renderer.bounds.size.x/2) + .01f);
else if(rotoAngle > 180)
temp.x += ((text.renderer.bounds.size.x/2) + .01f);

text.transform.position = temp;
text.text = item.Key;

//Adds Marker's position to the list of data points to be used as a vertex

//Adjusts angle of rotation for next access and parents current Axis
rotoAngle += angleNum;
axis.parent = this.transform;
}

//Displays graph
showGraph();
}

// Update is called once per frame
void Update () {

}

//Grabs Data
void getData() {
for( int i = 0; i < axisNum; ++i )
{
data.Add(("Stat " + (i+1)), Random.Range(25, 93));
}
}

//
void showGraph() {
GameObject chart = new GameObject("Block");	//GameObject mesh is assigned to
Mesh newMesh = new Mesh();					//Mesh to be used as Graph
chart.AddComponent<MeshFilter>();			//Filter and Renderer Necessary to display Mesh

//An array of the vertex points (as Vector3s) to be used for mesh
Vector3[] verts = new Vector3[points.Count];

//converts list of points to array (Mesh only accepts arrays
for( int i = 0; i < points.Count; i++ )
{
verts[i] = points[i];
}

//Assign verts to mesh
newMesh.vertices =  verts;

//Assign UVs to Mesh
Vector2[] uvs = new Vector2[newMesh.vertices.Length];
for ( int i=0; i < uvs.Length; i++ )
{
uvs[i] = new Vector2(newMesh.vertices[i].x, newMesh.vertices[i].z);
}
newMesh.uv = uvs;

//New Array for Mesh Tris
int[] tris = new int[(axisNum)*3];

int p1 = 1;		//first point of trangle other than origin (0) going counter clockwise
int p2 = 2;		//second point of trangle other than origin (0) going counter clockwise
int pLast = p1;		//Value for making the last triangle (and there for closing the mesh

//Assigns Tris in a clockwise fashion (counterclockwise diplays the mesh backwards)
for( int i = 0; i < (axisNum- 1)*3; i += 3 )
{
tris[i] = 0;
tris[i+1] = p2;
tris[i+2] = p1;

++p1;
++p2;
}

//Assigns end point of triangles, "closing" the mesh
tris[((axisNum)*3) - 3] = 0;
tris[((axisNum)*3) - 1] = p1;
tris[((axisNum)*3) - 2] = pLast;

//Assign Tris (I think we get it by now)
newMesh.triangles = tris;

//Assigning the mesh to gameObject and other fine details
newMesh.RecalculateNormals();
chart.GetComponent<MeshFilter>().mesh = newMesh;
chart.renderer.material = mater;