- Home /
ViewportToWorldPoint doesn't work as expected
Quick explanation: I use ViewportToWorldPoint to find the corners of the screen. However, the resulting points are not situated in the corners.
dist = Camera.main.transform.position.y - transform.position.y; // Camera above player
topLeft = Camera.main.ViewportToWorldPoint(Vector3(0,1,dist)); // Get top left point?
topRight = Camera.main.ViewportToWorldPoint(Vector3(1,1,dist)); // Get top right point?
startPoint = topLeft; // These are the start and end points for a lineRenderer line.
endPoint = topRight;
I think this can be shown best with pictures (sorry it's a bit huge). First image is in-game - the line is misaligned at the top. 2nd and 4th images show how it extends past the edges of the camera. 3rd image shows how it's correctly aligned on one axis. I am utterly confused. Any ideas? Thank you.
I've tried doing the same thing using raycasting and ViewportPointToRay, but the result is more or less the same. It's still misaligned, apparently offset towards the lower left corner of the screen.
Like this: var rayEnter : float;
ray = Camera.main.ViewportPointToRay(Vector3(0,0,0));
thePlane = Plane( Vector3.up, Vector3.zero ); // The XZ plane the game is played on
thePlane.Raycast(ray, rayEnter); // Find the distance along the ray that we contact the plane (it goes in rayEnter)
topLeft = ray.GetPoint(rayEnter); // Find the actual in-world position by going that far along the ray
Answer by aldonaletto · Dec 14, 2011 at 09:55 PM
The distance is from the camera to the "universe" plane, but the distance from the camera to the corners is larger. You could use the following:
var thePlane = Plane( Vector3.up, Vector3.zero ); // The XZ plane the game is played on var ray: Ray; var dist: float; ray = Camera.main.ViewportPointToRay(Vector3(0,1,0)); // topLeft ray thePlane.Raycast(ray, dist); // Find the distance to top left... topLeft = ray.GetPoint(dist); // Get the actual topLeft point ray = Camera.main.ViewportPointToRay(Vector3(1,1,0)); // topRight ray thePlane.Raycast(ray, dist); // Find the distance to topRight... topRight = ray.GetPoint(dist); // Get the actual topRight point
EDITED: Yes, this is very similar to your last code - an edition of it, to be more precise, but using the rays to find directly the topLeft and topRight points at the plane level.
ViewportPointToRay works fine - it must be declared not guilty. I suspect your problem is elsewhere: something in this script or any other is causing the shift. Where do you calculate the points, Start or Update? If in Start, something may be shifting the camera or the linerenderer object after the points are calculated (not sure if moving the linerenderer object may affect the line position). If in Update, the line should keep the correct position relative to the camera - again, unless something in another Update is doing the shift.
Thanks for trying but it didn't do it. There must be something more to it... I tried this (it's the same as the code I posted in a comment above) and it's still misaligned. What could possibly cause this?
I'm starting to think it's a weird interaction with some aspect of the way I've done something. ... wish that wasn't so vague.
Do you have LineRenderer.useWorldSpace checked? If not your linerenderer have to be placed at (0,0,0) with no rotation or the lines will of course have an offset since they are rendered in the local space of the linerenderer gameobject.
I was thinking it might be because the ship is moving, maybe the line position is calculated before the camera moves itself (and then the camera moves, making the line positions look wonky). But then, the lines are always shifted the same way relative to the screen, regardless of which way the player rotates the screen.
What I'm really working towards is drawing an arrow at the edge of the screen showing which way to go. I'm trying to find the 4 lines that make up the screen borders, so I can check intersections with them. It's complicated because the screen rotates with the player. If there's another way I could do that, I could skip this problem.