-
-
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(); | |
} |
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();
}
@nukadelic works like a charm, thanks!