I have a custom editor menu that creates new objects in the world. I would like the new objects to appear in the middle of the current scene view. My world is primarily a flat ground plane at y = 0, so I thought HandleUtility.GUIPointToWorldRay plus Plane.Raycast would do the trick, as per code fragment below.
private static Vector3 GetViewCenterWorldPos()
{
Vector2 screenCenter = new Vector3(Screen.width/2.0f, Screen.height/2.0f);
Ray worldRay = HandleUtility.GUIPointToWorldRay(screenCenter);
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
float distanceToGround;
groundPlane.Raycast(worldRay, out distanceToGround);
Vector3 worldPos = worldRay.GetPoint(distanceToGround);
return worldPos;
}
Everything looks reasonable -- screenCenter is correct for the Scene view, and worldPos has y = 0, as expected for a ground plane intersection. However, when I place an object at the worldPos location, it appears just offscreen above and left of the Scene view. This is consistent wherever I move the camera, the new object is always above and left.
Turns out that finding the worldRay like this works perfectly:
Ray worldRay = Camera.current.ViewportPointToRay(new Vector3(0.5f, 0.5f, 1.0f));
but only when Camera.current is accessible, which is true only if the Scene view was the most recently selected tab before I selected my custom menu item.
I also sometimes get this message:
Unable to convert GUI point to world ray if a camera has not been set up!
UnityEditor.HandleUtility:GUIPointToWorldRay(Vector2)
Overall it seems that either HandleUtility.GUIPointToWorldRay has a bug, or that I can't use it reliably from a custom menu item.
Advice appreciated.