Make character look at mouse position, not world position

Hello, I want my character to always face the mouse position. This is a isometric type game.

This is how i’ve done it now, in the Update function:

	//aiming
	var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
	var hit : RaycastHit;
	if (Physics.Raycast (ray,hit,1000)) {
		Debug.DrawLine (ray.origin, hit.point,Color.green);
		aimPos = Vector3(hit.point.x,upperBody.position.y,hit.point.z);
	}
	upperBody.LookAt(aimPos);

This sort of works, however. The character will look at objects sticking up out of the ground, as the camera ray hit’s them. This results in the player not being able to look parallel to a wall for example, since they will either look AT the wall, or at the ground beside it.

I know that I can put the objects that I don’t want the ray to collide with on an IgnoreRayCast layer, however, that creates another problem. If the character climbs up on a wall, and that wall is on ignore raycast, if the cursor is put below the character, it will still look up (away from the camera), since the ray from the camera passes through the wall that the character is standing on, and lands in front of the character.

What I want is basically: Whenever the cursor is below the character, it is supposed to look down. When it is above the character, it is supposed to look up, same things goes for left and right.

Could anyone please point me in the right direction?

Thanks.
/Alex

EDIT: Below is a screenshot of the issue. As you can see, the mouse cursor is below the character, but it doesn’t look towards the mouse, since the ray shoots through the object that the character is standing on. The objects need to ignore the raycast, since I always want the character to look at the mouse position, not at the objects. (The legs rotate independently of the upper body, they are irrelevant to this issue)

Hello! I managed to get it right, this is how I did it. Thanks cmonroy and jkpenner for explaining how the logic should be. Note how I use upperBodyToCursor.y instead of z, since z is the distance from the camera, not direction to mouse cursor.

//aiming
	//get the screen position of the upper body bone
	upperBodyScreenPos = Camera.main.WorldToScreenPoint(upperBody.position);
	
	//get the direction from the upper body to cursor
	upperBodyToCursor =  Input.mousePosition - upperBodyScreenPos;
	
	//set aimPos to upperbody position + direction vector
	aimPos = (upperBody.position + Vector3(upperBodyToCursor.x,upperBody.position.y,upperBodyToCursor.y));
	
	// transform aimPos to camera space
	finalAimPos = cameraDirTransform.TransformDirection(Vector3(aimPos.x,0,aimPos.z));
	
	//look at aimpos
	upperBody.LookAt(finalAimPos);
	
	//calculate movement relative to camera
	finalMovement = cameraDirTransform.TransformDirection(Vector3(horizontalInput,0,verticalInput));

Use WorldToScreenPoint instead of ScreenPointToRay

            Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
			RaycastHit hit;
			Vector3 direction;
			Quaternion rotation;
			if(Physics.Raycast (ray, out hit, 5f)) 
			{
				direction = (hit.point - transform.position).normalized;
			}
			else 
			{
				direction = ray.direction;
			}
			
			rotation = Quaternion.FromToRotation(transform.forward, direction);

This will shoot a raycast out from the center of your screen, it will then perform calculations to get the center of the screen if it hits something, and if it doesn’t it will simply turn towards the direction of the ray.

The origin of the ray should be located at your character’s location. The mouse position should be the end destination of the ray. The problem as I see it is that even though you have a definite X and Y values, the required Z (depth) is estimated for any geometry available at that spot and may not always be what you expect.

You could, however, create an invisible object at a fixed distance from your character (let’s say 2 meters) and provide the X and Y values from your Mouse position. Having the X, Y and Z components, just transform the position of the target and simply look at it.