How do I rotate a gameobject towards a point in world space?

I wanted to create a very simply turret. This turret should aim at the point on the screen where the mouse pointer is currently located.

I have added a cube to serve as a very simple turret in my scene. To visualize its aiming direction, I'm drawing a ray from it.

To rotate the "turret" to the mouse pointer position, I have created a script and added it to the "turret" gameobject:

void Update()
{
var mousePos = Input.mousePosition;
mousePos += Camera.main.transform.forward * 10f; // Make sure to add some "depth" to the screen point
var aim = Camera.main.ScreenToWorldPoint(mousePos);

transform.LookAt(aim);

RaycastHit hit;

int layerMask = 1 << 8;

Color color;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
color = Color.green;

}
else
{
color = Color.red;
}

Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 10000, color);
}


However, there must be something wrong in my code.

In this screenshot, I have added a red arrow that points to the position of the mouse pointer:

The mouse pointer is over that orange tool. However, the turret is rotated towards the floor while it should be rotated upwards to the orange tool.

I do believe that my turret is well positioned (the blue arrow points forward):

How do I change my code so that it aims correctly, and what is my mistake?

I guess the problem is in these 2 lines, but I don't see what's wrong about it:

    mousePos += Camera.main.transform.forward * 10f; // Make sure to add some "depth" to the screen point
var aim = Camera.main.ScreenToWorldPoint(mousePos);


Thank you.

Edit: I finally understand what Kevin wanted to tell me. I made a thinking mistake, and really need the Raycast to determine where my Worldspace point actually is.

Here is why:

Even though the Y screen coordinate of the mouse position is just a few pixels different in each game window on the right side, the worldspace point is totally different (as can be seen in the scene view window on the left side).

I thought in 2D space, while I should have thought in 3D space.

Your problem is indeed with the first few lines:

var mousePos = Input.mousePosition;
mousePos += Camera.main.transform.forward * 10f; // Make sure to add some "depth" to the screen point
var aim = Camera.main.ScreenToWorldPoint(mousePos);


Here you are adding the Camera's forward vector, which is in 3D, to a mouse's 2D coordinates. This is not going to add "depth" to the screen point, it's going to send it off in a seemingly random direction.

Do this:

var mousePos = Input.mousePosition;
mousePos.z = 10; // Make sure to add some "depth" to the screen point
var aim = Camera.main.ScreenToWorldPoint(mousePos);


Setting the z to a positive value like 10 is all you need to do; this moves the position we got from the cursor "forward" regardless of the orientation of the camera. When you convert to world space, the world space point will be in front of the camera where you expect it to be.

Alternatively, you might need to do a raycast to determine distance if it matters how far away the object under the cursor is:

Ray ray = Camera.main.ScreenPointToRay(mousePos);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
Vector3 target = hit.point;
}

• It would be really nice if you could just add a space or so to your answer, then I can upvote it again. It was really stupid: First I voted it up, then I thought that your answer didn't solve my problem, so I wanted to undo my upvote, and I clicked the down-arrow. However, this didn't result in my upvote being removed, but instead it would even downvote your answer. This was absolutey not what I wanted to do. Then I wanted to click the up arrow again, but stackexchange told me that this is only possible if you edit your question. Commented Jul 19, 2020 at 8:20