I have a NavMeshAgent placed on a character model. When I log agent.transform.position I get (4.5, 0.1, 4.5) which is correct (this is a 2.5d game and movement happens along the x and z axes).

I am trying to set up a script so that when I click a location on the screen, the character will turn to face that location.

The problem I'm facing is that the coordinates returned by Camera.ScreenToWorldPoint are not correct:

Vector3 mousePos = Input.mousePosition;
mousePos.z = Camera.main.nearClipPlane;
Vector3 targetPos = Camera.main.ScreenToWorldPoint(mousePos);

// Logs: (4.5, 0.1, 4.5)

// Logs: (0.1, 16.7, 0.7)

In this example, I'm clicking on the same place as the agent but the targetPos is not nearly the same.

The y-axis of targetPos is static (the same no matter where I click), which seems correct. However the values for x and z are not correct. How do I get the correct coordinates for a click?

edit I have this workaround, but I want to know how to solve the original question still:

RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100, rotateTargets))
    Vector3 targetPos = hit.point;
    targetPos.y = agent.transform.position.y;
    Vector3 direction = (targetPos - agent.transform.position).normalized;
    Quaternion rotation = Quaternion.LookRotation(direction);
    agent.transform.rotation = rotation; 
    agent.updateRotation = false;
    return true;
  • \$\begingroup\$ Why did you choose the camera near plane for your z? This will tend to put all output points very close to your camera, rather than near the level geometry you're clicking on (since you'll usually have your near plane set much closer than the stuff you're drawing, so it doesn't get clipped out) \$\endgroup\$ – DMGregory Jul 1 '18 at 23:02
  • \$\begingroup\$ @DMGregory it's part of the example given in the docs. I tried replacing it with agent.transform.position.y, but if I do that then targetPos does not change at all no matter where my mouse is. \$\endgroup\$ – max pleaner Jul 1 '18 at 23:07
  • \$\begingroup\$ I should also mention, I did figure out a workaround using a raycast (see edit to question). However I still want to know how it can be tied to the mouse position without raycast. \$\endgroup\$ – max pleaner Jul 1 '18 at 23:16
  • \$\begingroup\$ A raycast is the correct solution when you want to find where a line from your eye through the mouse meets the terrain / other object in the game world. There are special cases you can solve for if you know a priori that you want a point on a particular plane or other geometric primitive, but without that a mouse position still leaves you with a degree of freedom that you need to fill in by specifying a depth along that camera-mouse ray. \$\endgroup\$ – DMGregory Jul 1 '18 at 23:19
  • \$\begingroup\$ @DMGregory Ok the main issue is I want the user to be able to click on empty space and still rotate to that position. Although I suppose I could just fill the empty space with an invisible plane. In the case without the raycast, though, I do provide the Z, so why is the position wrong? \$\endgroup\$ – max pleaner Jul 1 '18 at 23:22

I needed to use Camera.main.position.y - agent.transform.position.y as the value for z on ScreenToWorldPoint.

The reason is that the z argument in this case should be the distance between the camera and the ground, not the ground's position relative to 0.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.