[ExecuteAlways] public class SampleMonoBehaviour : MonoBehaviour { private void OnEnable() { SceneView.duringSceneGui += SceneGUI; } private void SceneGUI(SceneView sceneView) { var pos = sceneView.camera.WorldToViewportPoint(transform.position); Handles.BeginGUI(); GUI.Label(new Rect(pos, new Vector2(100, 12)), "test"); Handles.EndGUI(); } }
上記のように、sceneView のカメラから Viewport座標を取得しても正しい位置に表示されない
それもそのはずで、GUI の描画に利用してるのは Viewport座標を利用していないため、
Window のサイズに合わせて適切に変換してあげる必要がある
その変換処理が以下
public static class SceneViewHelper { /// <summary> /// WorldToViewportPoint は Toolbar のサイズを考慮していないため考慮して計算する /// </summary> public static Vector3 SceneViewWorldToScreenPoint(SceneView sceneView, Vector2 worldPosition) { var pointInView = sceneView.camera.WorldToViewportPoint(worldPosition); var screenPosition = pointInView * sceneView.position.size; screenPosition.y = sceneView.position.height - screenPosition.y; return screenPosition; } }
これを利用して先程の処理を書き換えるとこうなる
private void SceneGUI(SceneView sceneView) { var pos = SceneViewHelper.SceneViewWorldToScreenPoint(sceneView, transform.position); Handles.BeginGUI(); GUI.Label(new Rect(pos, new Vector2(100, 12)), "test"); Handles.EndGUI(); }
これで正しい位置に表示させることができる