- Home /
Vector2 Editor Visualization
Hi, I'm looking for ideas on how to approach creating an editor sort of like the one for CSGO Bullet Spray.
The idea I had was to just not touch the array editor, and display all of the positions on some sort of canvas below. Then change the color of the dots with lerp based on their position in the array. I'm just not sure how I would create such a canvas and display the dots.
Answer by troien · Jan 03, 2019 at 08:30 PM
Another option could be to use the previewGUI for this. Idea is similar to the other answer you posted, but added some logic to convert units to pixels and center it. You can ofcourse copy/paste the code in DrawPreview to OnInspectorGUI where you can get the original rect using
Rect rect = EditorGUILayout.GetControlRect(false, heightInPixels);
if you prefer to do that instead.
[CustomEditor(typeof(Example))]
public class ExampleInspector : Editor
{
private SerializedProperty _vectors;
private void OnEnable()
{
_vectors = serializedObject.FindProperty("vectors");
}
// Helper method to get a square rectangle of the correct aspect ratio
private Rect GetCenteredRect(Rect rect, float aspect = 1f)
{
Vector2 size = rect.size;
size.x = Mathf.Min(size.x, rect.size.y * aspect);
size.y = Mathf.Min(size.y, rect.size.x / aspect);
Vector2 pos = rect.min + (rect.size - size) * 0.5f;
return new Rect(pos, size);
}
public override bool HasPreviewGUI()
{
return true;
}
public override GUIContent GetPreviewTitle()
{
return new GUIContent("My example");
}
public override void DrawPreview(Rect rect)
{
rect = GetCenteredRect(rect);
// Draw background of the rect we plot points in
EditorGUI.DrawRect(rect, new Color(0.8f, 0.8f, 0.8f));
float dotSize = 5; // size in pixels of the point we draw
float halfDotSize = dotSize * 0.5f;
float viewportSize = 10; // size of our viewport in Units
// a value of 10 means we can display any vector from -5,-5 to 5,5 within our rect.
// change this value for your needs
for (int i = 0; i < _vectors.arraySize; i++)
{
SerializedProperty vectorProperty = _vectors.GetArrayElementAtIndex(i);
Vector2 vector = vectorProperty.vector2Value;
Vector2 normalizedPosition = vector / new Vector2(viewportSize, -viewportSize);
if (Mathf.Abs(normalizedPosition.x) > 0.5f || Mathf.Abs(normalizedPosition.y) > 0.5f)
{
// don't draw points outside our viewport
continue;
}
Vector2 pixelPosition = rect.center + rect.size * normalizedPosition;
EditorGUI.DrawRect(new Rect(pixelPosition.x - halfDotSize, pixelPosition.y - halfDotSize, dotSize, dotSize), Color.blue);
}
}
}
This seems like a really great solution and better option to what I came up with. I was having an issue with the coloring, and this solved it as well.
I can't thank you enough for this!
Answer by ZhavShaw · Jan 03, 2019 at 07:56 PM
Rect rect = new Rect(20, 500, 300, 300);
GUI.BeginGroup(rect, "Spray Pattern", GUI.skin.box);
for (int i = 0; i < Pattern.arraySize; i++)
{
float x = Pattern.GetArrayElementAtIndex(i).vector2Value.x * 100;
float y = Pattern.GetArrayElementAtIndex(i).vector2Value.y * 100;
Rect r = new Rect(x - 3.5f, y - 3.5f, 7, 7);
GUI.Box(r, i.ToString());
}