- Home /
How do I draw lines in a custom inspector?
I have a custom inspector, and I wish to draw lines, in order to provide some graphing functionality.
I have looked everywhere for a reliable answer, but I can not find anything for the actual inspector. I can create a new editor window to draw in, and I can draw to the actual scene view, but for my desired result I need to specifically draw in the inspector.
It was suggested that I directly call OpenGL commands, but that does not work, either. It is entirely possible that my problem is actually in deriving the correct screen position of which to draw to, but again, I am not entirely sure how I would do that. As is, my attempts to draw have come up with nothing.
How do I draw lines in a custom inspector?
Answer by Bunny83 · Jun 01, 2017 at 10:49 AM
Here's an example how to setup a proper GL viewport inside a custom inspector:
edit
I just did some additional tests and it seems it's a bit too difficult to setup a custom viewport inside the inspector as it would require detailed information about the InspectorWindow itself. That's because the rendering context generally has it's origin at the bottom left. To calculate the correct top left corner you need to know the overall height of the Inspector window.
I've created a more concrete example that will draw a framerate diagram in the inspector at runtime without setting a custom viewport, but just using the default GUI viewport and current matrix setup. This solves all coordinate problems but you have to take care about where you draw. You can easily draw anywhere inside the inspector window.
Material mat;
private void OnEnable()
{
var shader = Shader.Find("Hidden/Internal-Colored");
mat = new Material(shader);
}
private void OnDisable()
{
DestroyImmediate(mat);
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
Rect rect = GUILayoutUtility.GetRect(10, 1000, 200, 200);
if (Event.current.type == EventType.Repaint)
{
GUI.BeginClip(rect);
GL.PushMatrix();
GL.Clear(true, false, Color.black);
mat.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.black);
GL.Vertex3(0, 0, 0);
GL.Vertex3(100, 100, 0);
GL.End();
GUI.EndClip();
}
}
Here's the whole example as unitypackage. The result looks like this:
To explain some parts of that code snippet:
GUILayoutUtility.GetRect(10,10000,200,200)
reserves a layout rectangle inside the custom inspector. The width is automatically adapted to the enclosing layout group (minwidth 10 and maxwidth 10000). The height is forced to 200 pixel.GUI.BeginClip(rect)
starts a new clipping area with the rect we just created. That makes all GUI coordinates relative to that areaGL.Clear
will clear the whole viewport. In my example i only clear the depth buffer. Note that GL.Clear will clear the whole Viewport which is in case of a custom inspector the whole Inspector window. So clearing with a color shouldn't be used.mat.SetPass(0)
it is important to enable a shader pass before you do any rendering. Otherwise Unity would use whatever shader was previously active and that could be quite random.
Some additional notes:
GUILayoutUtility.GetRect must be called outside of the EventType check. It's important that this is executed for the Layout and Repaint event.
Any direct drawing has to be restricted to the Repaint event.
If you don't use an orthographic projection you have to watch your z position.
I am still to have a play around with this, but you've provided a working example, so I know this answers my question 100%. One more question; do you have a Stack Exchange account? I asked about this, a little while ago, on the Game Dev Stack Exchange; but noone was able to answer. Once I can put this in my own words, I will be answering my question to mark it as complete, but if you have an account, I welcome you to copy-paste this answer in.
https://gamedev.stackexchange.com/questions/141302/how-do-i-draw-lines-to-a-custom-inspector
If you get $$anonymous$$atrix stack full depth reached
, you need to add a GL.Pop$$anonymous$$atrix();
. (Stackoverflow version of this has a full example.)
Hello @Bunny83, your solution is very smart but for some reason suffers from a very low update rate. Is there a way to draw a line in the inspector at actual frame rate?
I'm not quite sure what you mean.In the past, when in play mode, the inspector was updated once per frame. However they now introduced the RequiresConstantRepaint property which allows you to specify when you need a constant repaint for your editor. This is what I used in my example, even in a quite naive way.
Without this property returning true the inspector in general only updates when a user interaction happens or when a repaint is requested by some editor code. most component inspectors do not need to be redrawn every frame since the information shown usually doesn't change on a frame to frame basis.
@Bunny83 thank you for your reply. As far as I know, RequiresConstantRepaint let you "check if this editor requires constant repaints in its current state", but doesn't allow you to set ConstantRepaint property. I also tried to call Repaint() after every draw, but it doesn't seem to change a lot.
I had a also a look to EditorApplication.update but i couldn't make it work. Any suggestion?
Answer by Yany · Oct 07, 2021 at 11:06 PM
Maybe I'm just lucky, but this works to me in Unity 2021.1.19 like a charm without any low-level GL instructions:
...
GUI.BeginClip(rect);
Handles.color = Color.red;
Handles.DrawAAPolyLine(Texture2D.whiteTexture, lineWidth, point1, point2, point3, ...);
GUI.EndClip();
...
I appreciate any feedback if this works for anybody else too, thank you.
Your answer
![](https://koobas.hobune.stream/wayback/20220612123242im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
OnInspectorGUI Custom Drawing? 1 Answer
Loss of GO selection 2 Answers
How is the rotation of a Transform converted into a Vector3 in the inspector ? 2 Answers
Inspector turns black on refresh 4 Answers
DropDown Menu In Inspector? 1 Answer