- Home /
The question is answered, right answer was accepted. Just double-check your understanding of ScreenToWorldSpace, and check your camera settings
Camera.main.ScreenToWorldPoint not working as expected
Hi there. So at the moment, I am trying to get some character movement going based on where a player is touching the screen. Here is the code I have so far
void Update()
{
MoveReady();
}
public void MoveReady()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
TouchRegistered(touch);
}
}
private void TouchRegistered(Touch touch)
{
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
//Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
Vector3 touchPosition = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, transform.position.y, transform.position.z));
print(touch.position);
print(transform.position.x);
print(touchPosition);
var direction = touch.position.x - transform.position.x;
print(direction);
}
}
I know there isn't any code in there to actually make the player move, but that's because I am not there yet. The problem I am running into is when I run Camera.main.ScreenToWorldPoint(touch.position), I get (0, 0, -10). Now for reference, (0,0,-10) is the position of the camera. I am not sure what I am doing wrong here as this code had worked before, but maybe I'm not seeing something?
Any and all help is greatly appreciated. Thank you for the time!
Answer by Bunny83 · Jan 24, 2020 at 02:41 AM
You have a totally wrong idea of what ScreenToWorldPoint does. You have to provide a screen space coordinate in x and y and in z you have to provide the desired distance from the camera in world units. Your usage of transform.position as input for the method makes no sense. This is already a world space coordinate. If your camera is a perspective camera that means at a zero distance (passed in z value of 0) you always get back the camera position since with a perspective camera all perspective lines meet at the camera origin.
We don't know how you want to use the world space coordinate. Though it seems you just want to move your player left and right. For an orthographic camera the distance from the camera doesn't matter. However for a perspective camera you need to use the proper distance to get the right projected position. To calculate the distance of your player from the camera you can use the dot product between the relative vector from your camera to your player and the camera's forward vector
Vector3 touchPos = touch.position;
Transform camTrans = Camera.main.transform;
float dist = Vector3.Dot(player.transform.position - camTrans.position, camTrans.forward);
touchPos.z = dist;
Vector3 pos = Camera.main.ScreenToWorldPoint(touchPos);
// do whatever you want with the projected position. For example just set the players x position based on the projected position:
Vector3 tmp = player.transform.position;
tmp.x = pos.x;
player.transform.position = tmp;
Bless up! Thank you! You're definitely correct in saying my understanding of ScreenToWorldPoint was all goofy, but what especially tripped me up was the camera and its perspective setup.
Thank you for your time and for the swift, correct response
Hi, I used you method (Bunny83) and I cant get the y axis to work. After tmp.x = pos.x, I wrote tmp.z = -pos.y (I have a view from above) but it aint working. Could you help me?