I come seeking guidance on how to properly use Camera.ViewPortToWorldPoint. My understanding is that I can use this to convert a point on the viewport to a point in world space, but even after hours of searching I am having a difficult time finding information on how to properly use it.
Yes, I did look at the Scripting API.
Here is what I am trying to do: I want to take a position on the viewport and translate it to a position in world space so that I can use that information to set the transform position of a gameobject.
What exactly are you struggling with? Syntax? Other results than expected? Provide more information and you’ll get help.
And yes, the method does exactly what you’re after, note that this method is using normalized values instead of pixel values (for the latter you could use ScreenPointToWorld).
Viewport space is great for all those times you don’t want to deal with screen space. (for example: ALL the time.) No worries about how big or what resolution the screen is- because viewport space is relative. (0,0) is the lower left corner, (1,1) is the upper right- simple.
Sometimes, you may need to get the world space coordinates of, say just off center screen- (.5, .45). Naturally, the screen is a 2D plane and world space is 3D, so the “z component is the distance of the resulting plane from the camera.”
Syntax is pretty easy. Pretty much like @LMan_1 has already explained.
You only need to pass in a position of your view port, usually something in between (0,0) and (1,1) and a z value. The z value is used to determine a plane parallel to your view port, so that view port and said plane have a distance of z.
What you’ll get back is a Vector3 that describes the world position.
The following script makes the object (e.g. a sprite for testing) cross your screen from the lower left to the upper right corner, it moves along the plane that is 1 unit (z = 1) in front of the camera.
using UnityEngine;
public class Test : MonoBehaviour
{
private float _progress;
private void Update()
{
var nextPos = new Vector3(_progress, _progress, 1);
transform.position = Camera.main.ViewportToWorldPoint(nextPos);
_progress += Time.deltaTime * 0.2f; // takes ~ 5 seconds to cross the screen
}
}
Working with sprites, the only thing you should take note of is that z > nearClipPlane of the camera, otherwise it’ll not be rendered.
Working with 3D objects, you may want to make sure you do not choose a plane that is too close, otherwise you’ll experience annoying visual effects ranging from non-rendering, flickering, to partly-rendererd meshes. Make sure you choose a reasonable distance that prevents these issues and also favors your gameplay mechanics.
Thank you for your response. A follow-up question:
Suppose that I just want to place a sprite at a specific position relative to the viewport like (0.1, 0.1) for near the bottom left corner. How would I write that?
You should be able to answer this on your own, but I’ll describe it roughly. Putting this into code will be your job.
First of all, if you want to place it at that specific position, it’s a one-time action. You wouldn’t need Update() for it, but you can use e.g. Start().
Next, have a look at the snippet again. As mentioned, the method takes a Vector3. In my example, this Vector3 changes over time. You only need it to be(0.1f, 0.1f, z) where z should be a positive value. The _process variable is not needed, as you don’t want to change its position.
I was successful in achieving my goal, but it seems I always need to establish a Vector3 as a variable and use the variable in my Start() code. Is it not possible to input a Vector 3 directly into my code in Start()? Trying the following does not work: