Problem with rotation script.

I am trying to make an object always rotate to face the mouse using a script that I found searching for a solution for this problem.

function Update () {

var mousePos = Input.mousePosition;
mousePos.z = 10.0f; //The distance from the camera to the player object
var lookPos :Vector3=Camera.main.ScreenToWorldPoint(mousePos);
lookPos = lookPos - transform.position;
var angle : float = Mathf.Atan2(lookPos.y, lookPos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

}

The problem is the mouse always seem stick to the right side of the object. Not sure how to fix this.

ScreenToWorldPoint apparently always returns the center of the camera, not the mouse position. Although I could be wrong about that.

Post describing this concept further.

The best way is to use raycasting with a similar function, ScreenPointToRay.

This is a simple C# script that snaps the Transform to face the mouse, from a topdown perspective. With a little tweaking of vectors it should work perfect for you as well from the side. (You could probably use only X and Y and set Z to 0)

using UnityEngine;
using System.Collections;

public class RotateToMouse : MonoBehaviour {
	
	public Vector3 lookPos;
	
	// Update is called once per frame
	void Update () 
	{
		
		var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		RaycastHit hit = new RaycastHit();
		if (Physics.Raycast(ray, out hit))
		{

			lookPos = new Vector3 (hit.point.x, 0f, hit.point.z);
			
			transform.LookAt(lookPos);
		
		}
	}
	
}

One thing to watch out for is that you absolutely MUST have a collider that the ray will hit, otherwise you will get a null reference exception. You could just add a public LayerMask that only hits the collider’s layer to the script, set up the collider in a separate layer, and then add the LayerMask variable to the Physics.Raycast(ray, out hit, HERE).

The “0f” in the look position in the “Y” spot is so that no matter how close or far away the collider is it always sets the lookPos “Y” position to absolute zero. That way the object does not look up or down in a 2D environment, which would probably look odd.

I hope that helps!

Thanks, and God bless!

Howey

In a 2D game the best way is to use ScreenToWorldPoint having set the Z position of the 2D plane.

  var pos = (Vector3)Input.mousePosition;
  pos.z = distanceTo2DPlaneFromCamera;
  var worldPoint = Camera.main.ScreenToWorldPoint(pos);

The code above only works with the right setup:

  1. The camera must be looking at positive Z with no rotation on any of the axes.

  2. Line 4 is the distance in front of the camera to the 2D plane of your game. If you prefer a calculation you can use:

    var lookPos = Mathf.Abs(transform.position.z - Camera.main.transform.position.z);

  3. The script must be attached to the object that rotates, and the center of rotation of the object must match the the origin of the object.

  4. The initial rotation of the object must be (0,0,0).