-
-
Save Arakade/9dd844c2f9c10e97e3d0 to your computer and use it in GitHub Desktop.
static void drawString(string text, Vector3 worldPos, Color? colour = null) { | |
UnityEditor.Handles.BeginGUI(); | |
if (colour.HasValue) GUI.color = colour.Value; | |
var view = UnityEditor.SceneView.currentDrawingSceneView; | |
Vector3 screenPos = view.camera.WorldToScreenPoint(worldPos); | |
Vector2 size = GUI.skin.label.CalcSize(new GUIContent(text)); | |
GUI.Label(new Rect(screenPos.x - (size.x / 2), -screenPos.y + view.position.height + 4, size.x, size.y), text); | |
UnityEditor.Handles.EndGUI(); | |
} |
I passed a color and it made the whole scene view that color. I just removed it, and it satisfied what I intended. Well done! Thanks
Hey I used this code and it works great! Except, I was thinking of visualizing coordinates so I did the following:
void OnDrawGizmos()
{
int xSize = 10, ySize = 10, zSize = 10;
for (int z = 0; z < zSize; z++)
{
for (int y = 0; y < ySize; y++)
{
for (int x = 0; x < xSize; x++)
{
drawString(x + ", " + y + ", " + z, new Vector3(x, y, z), Color.black);
}
}
}
}
Try this out.. Problem is it works nicely when you're in the proper spot, but if you keep diving into it, suddenly everything gets trippy and weird. What's happening? I suspect it's something to do with the WorldToScreenPoint section
Edit: I fixed it! Check it out:
static void drawString(string text, Vector3 worldPos, Color? colour = null)
{
UnityEditor.Handles.BeginGUI();
if (colour.HasValue) GUI.color = colour.Value;
var view = UnityEditor.SceneView.currentDrawingSceneView;
Vector3 screenPos = view.camera.WorldToScreenPoint(worldPos);
if (screenPos.y < 0 || screenPos.y > Screen.height || screenPos.x < 0 || screenPos.x > Screen.width || screenPos.z < 0)
{
UnityEditor.Handles.EndGUI();
return;
}
Vector2 size = GUI.skin.label.CalcSize(new GUIContent(text));
GUI.Label(new Rect(screenPos.x - (size.x / 2), -screenPos.y + view.position.height + 4, size.x, size.y), text);
UnityEditor.Handles.EndGUI();
}
I fixed the colour stuff. You need to restore the GUI colour after drawing.
static public void drawString(string text, Vector3 worldPos, Color? colour = null) {
UnityEditor.Handles.BeginGUI();
var restoreColor = GUI.color;
if (colour.HasValue) GUI.color = colour.Value;
var view = UnityEditor.SceneView.currentDrawingSceneView;
Vector3 screenPos = view.camera.WorldToScreenPoint(worldPos);
if (screenPos.y < 0 || screenPos.y > Screen.height || screenPos.x < 0 || screenPos.x > Screen.width || screenPos.z < 0)
{
GUI.color = restoreColor;
UnityEditor.Handles.EndGUI();
return;
}
Vector2 size = GUI.skin.label.CalcSize(new GUIContent(text));
GUI.Label(new Rect(screenPos.x - (size.x / 2), -screenPos.y + view.position.height + 4, size.x, size.y), text);
GUI.color = restoreColor;
UnityEditor.Handles.EndGUI();
}
I see this is a few years old, but just wanted to say thank you for this very useful bit of code and that it is still working great in 2018.3.8f1!
You can use handles inside the gizmo draw function instead like so :
void OnDrawGizmos()
{
#if UNITY_EDITOR
UnityEditor.Handles.color = Color.white;
UnityEditor.Handles.Label( pointA.position, "Point A" );
#endif
}
it also has overloads for texture and style ( font size can be changed )
@nukadelic works like a charm, thanks!
Thanks all for the snippet and tweaks! Based on the GUI version above, I further improved by using GUIStyle
to specify color and font size without having to use the color restore logic. I also added pixel-precise positioning with anchor support (e.g. Vector2.zero
= center, Vector2.one
= anchor to bottom-left corner, -Vector2.one
= anchor to top-right corner, etc.). The fudge factor issue is fixed by using camera.pixelHeight
instead of view.position.height
.
static public void drawString(string text, Vector3 worldPosition, Color textColor, Vector2 anchor, float textSize = 15f)
{
#if UNITY_EDITOR
var view = UnityEditor.SceneView.currentDrawingSceneView;
if (!view)
return;
Vector3 screenPosition = view.camera.WorldToScreenPoint(worldPosition);
if (screenPosition.y < 0 || screenPosition.y > view.camera.pixelHeight || screenPosition.x < 0 || screenPosition.x > view.camera.pixelWidth || screenPosition.z < 0)
return;
var pixelRatio = UnityEditor.HandleUtility.GUIPointToScreenPixelCoordinate(Vector2.right).x - UnityEditor.HandleUtility.GUIPointToScreenPixelCoordinate(Vector2.zero).x;
UnityEditor.Handles.BeginGUI();
var style = new GUIStyle(GUI.skin.label)
{
fontSize = (int)textSize,
normal = new GUIStyleState() { textColor = textColor }
};
Vector2 size = style.CalcSize(new GUIContent(text)) * pixelRatio;
var alignedPosition =
((Vector2)screenPosition +
size * ((anchor + Vector2.left + Vector2.up) / 2f)) * (Vector2.right + Vector2.down) +
Vector2.up * view.camera.pixelHeight;
GUI.Label(new Rect(alignedPosition / pixelRatio, size / pixelRatio), text, style);
UnityEditor.Handles.EndGUI();
#endif
}
@nukadelic great solution! Simple! Thanks!
Thanks a lot, works great!
For those who wonder what this pixelRatio is about: it depends on the display UI scaling (e.g. 1.5 for the '150%' setting in windows)
Instead of computing it, you can actually just get it using
var pixelRatio = EditorGUIUtility.pixelsPerPoint;
(see https://docs.unity3d.com/ScriptReference/EditorGUIUtility-pixelsPerPoint.html)
Very neat, exactly what I was looking for!
I passed a color and it made the whole scene view that color. I just removed it, and it satisfied what I intended. Well done! Thanks
I solved the issue color issue and also fixed the scene zoom text slipping
public static void DrawString(string text, Vector3 worldPos, Color? colour = null)
{
UnityEditor.Handles.BeginGUI();
Color defaultColor = GUI.color;
if (colour.HasValue) GUI.color = colour.Value;
var view = UnityEditor.SceneView.currentDrawingSceneView;
Vector3 screenPos = view.camera.WorldToScreenPoint(worldPos);
Vector2 size = GUI.skin.label.CalcSize(new GUIContent(text));
GUI.Label(new Rect(screenPos.x - (size.x / 2), -screenPos.y + view.position.height - size.y * 2, size.x, size.y), text);
GUI.color = defaultColor;
UnityEditor.Handles.EndGUI();
}
It works quite well!
However the "height fudge factor" (where you add + 4) seems to depend on the scene. Have not quite wrapped my head around it yet.
In my scene where the text is several hundred units high, the fudge factor is about 25.