- Home /
I want to rotate an object towards mouse position on screen in 3d environment. How can I do this?
I mean where the mouse or cursor position is, object should be facing towards all the time.
Answer by GregoryFenn · Jun 03, 2019 at 07:44 PM
Here's a fairly short and (IMO) sleek C# class file (a MonoBehaviour component) you can use for this kind of problem.
using UnityEngine;
public class MoveToMouse : MonoBehaviour
{
// e.g. 0.2 = slow, 0.8 = fast, 2 = very fast, Infinity = instant
[Tooltip("If rotationSpeed == 0.5, then it takes 2 seconds to spin 180 degrees")]
[SerializeField] [Range(0,10)] float rotationSpeed = 0.5f;
[Tooltip("If isInstant == true, then rotationalSpeed == Infinity")]
[SerializeField] bool isInstant = false;
Camera _camera = null; // cached because Camera.main is slow, so we only call it once.
void Start()
{
_camera = Camera.main;
}
void Update()
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
Quaternion targetRotation = Quaternion.LookRotation(ray.direction);
if (isInstant)
{
transform.rotation = targetRotation;
}
else
{
Quaternion currentRotation = transform.rotation;
float angularDifference = Quaternion.Angle(currentRotation, targetRotation);
// will always be positive (or zero)
if (angularDifference > 0) transform.rotation = Quaternion.Slerp(
currentRotation,
targetRotation,
(rotationSpeed * 180 * Time.deltaTime) / angularDifference
);
else transform.rotation = targetRotation;
}
}
}
Seems to work very well for me and seems to answer the question, so anyone who comes here can use/adapt/hack my code :) Let me know if I made any mistakes or you have some suggestions to improve, although it works super smoothly and intuitively in my star-fox style rail shooter game I'm making with Ben Tristem's GameDev_dot_TV course on Udemy ("C# Unity Developer 3D").
I was stuck on this for a couple of days trying to get the rotation of my blasters correct (I'm also doing Ben Tristem's Unity course) and this worked beautifully. A huge thank you for the assistance!
Answer by Cornelis-de-Jager · Jul 30, 2017 at 09:36 PM
Here is a simple solution. It works but has it downsides.
Camera cam;
// Use this for initialization
void Start () {
cam = Camera.main;
}
// Update is called once per frame
void Update () {
Ray ray = cam.ScreenPointToRay(Input.mousePosition);;
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
Vector3 target = hit.point;
target.y = 0;
target.y = transform.localScale.y / 2f;
transform.LookAt (target);
}
}
Answer by andrew-lukasik · Jul 30, 2017 at 09:39 PM
using UnityEngine;
public class Example : MonoBehaviour
{
//assign this field in inspector:
public Transform subject;
public float _depthOffset = 0f;
Camera _camera;
void Start ()
{
//copy a reference to main camera, for both convenience and performance:
_camera = Camera.main;
}
void Update ()
{
//update rotation:
Vector3 mousePositionWorldSpace = _camera.ScreenToWorldPoint( Input.mousePosition );
Vector3 pointOfInterest = mousePositionWorldSpace+_camera.transform.forward*_depthOffset;
Vector3 direction = pointOfInterest-subject.position;
subject.rotation = Quaternion.LookRotation( direction );
}
}
Answer by Game_Maker21 · Dec 26, 2020 at 12:06 AM
I coded it so that the rotating object looks at the mouse even with or without a raycast hit. This should work. I basically combined the answers from @GregoryFenn and @Cornelis-de-Jager
public Camera cam;
public Transform obj;
public float rotationSpeed;
void Update()
{
Quaternion currentRotation = obj.rotation;
Quaternion targetRotation;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
targetRotation = Quaternion.LookRotation(hit.point - obj.position);
}
else
{
targetRotation = Quaternion.LookRotation(ray.direction);
}
float angularDifference = Quaternion.Angle(currentRotation, targetRotation);
if (angularDifference > 0)
{
obj.rotation = Quaternion.Slerp
(
obj.rotation,
targetRotation,
rotationSpeed * Time.deltaTime
);
}
else
{
obj.rotation = targetRotation;
}
}