- Home /
Rotating a 3D object on the Y axis relative to the cursor's position?
I'm trying to combine the implied camera perspective of classic 2D Zelda titles with the controls of twin-stick shooters, in 3D. I can move the player with the WASD keys, but I'm not sure how to rotate him to face the mouse cursor. I think I need to do the following:
Calculate the cursor's position on the screen.
Draw a line between that position and the player character.
Calculate the difference between the player character's current Y axis rotation and that line.
Rotate the player character on the Y axis by that difference, so that the difference becomes 0.
This way if the player moves the cursor to the top of the screen the character will look "North"; if the player puts the cursor in the bottom left corner, the character will look "Southwest", if that makes sense.
I tried using transform.LookAt, but this caused a crazy feedback loop that made the character spin out of control:
Ray mouseRay = playerCamera.ScreenPointToRay(Input.mousePosition);
float midPoint = (transform.position - playerCamera.transform.position).magnitude * 0.5f;
transform.LookAt(mouseRay.origin + mouseRay.direction * midPoint);
I also tried the Brackey's tutorial here, but was unable to calculate the lookDir because ScreenToWorldPoint
returns a Vector2, while a 3D object's transform.position
is a Vector3.
Any ideas?
Answer by Acegikmo · Apr 28, 2020 at 08:37 PM
I'd raycast against a mathematical plane at the height of the player, then use look rotation!
Ray mouseRay = playerCamera.ScreenPointToRay(Input.mousePosition);
Plane p = new Plane( Vector3.up, player.position );
if( p.Raycast( mouseRay, out float hitDist) ){
Vector3 hitPoint = mouseRay.GetPoint( hitDist );
player.LookAt( hitPoint );
}
Thank you for your answer, @Acegikmo! I've accepted this one because of your idea to bounce the Raycast off of a plane at the height of the player character ins$$anonymous$$d of whatever the cursor happens to be over. $$anonymous$$y testing found that this prevents the character rotation from "hanging" on bumps in the terrain or obstacles placed upon it!
Your answer is exactly what i was looking for @Acegikmo. But the rotation gets messed up when the mouse is exactly over the player. it keeps rotating around itself like crazy. How do i solve that?
Answer by Cassos · Apr 28, 2020 at 08:44 PM
So sounds like you just need help with the player looking at the mouse. This should work out:
void Update()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
transform.LookAt(hit.point); // Look at the point
transform.rotation = Quaternion.Euler(new Vector3(0, transform.rotation.eulerAngles.y, 0)); // Clamp the x and z rotation
}
}
It will the player rotate on the y-axis only. To be honest, I'd add a Vector3.Lerp just to make it more smooth! ^^
Greetings,
Max
Hi @Cassos, thank you for your answer! I'm not familiar with Vector3.Lerp; how would it fit into this?
It basicly just smooth out the rotation so it doesn't instantly turn to it but needs some time