- Home /
Rotate sprite to face direction of movement
Hey folks, I have been bashing my head on this for a week now trying out all kinds of different methods and I feel like this should be easier than I'm making it. However nothing I have tried thus far works.
I am making a top down sprite character that moves exactly with the mouse cursor. This part works just fine, but I also want it to face the direction it is moving in but I just cannot get it to rotate on the Z axis so that it remains flat to the camera but rotates around to face its movement direction.
I've been trawling through various topics here, on youtube, stackoverflow, I am at a loss and its driving me nuts that I feel it should be a really simple thing to achieve but it just doesn't seem to be a done thing. a lot of the "follow cursor" methods require the object to follow the direction of the cursor, not be exactly on the cursors position, which, isn't what I'm aiming at. I want it to be exactly at the point of the cursor.
Here's my code, what rotation to direction of travel method using this cursor movement method would you recommend here?
{
private Vector3 pos;
void Awake()
{
//Cursor.visible = false;
}
void Update()
{
pos = Input.mousePosition;
pos.z = 980f; //positions at Z =0 from the camera, camera is at -980 Z.
Debug.Log("pos.x");
Debug.Log("pos.y");
}
private void FixedUpdate()
{
transform.position = Camera.main.ScreenToWorldPoint(pos);
}
}
Answer by kittymuffin · Aug 12, 2021 at 08:00 PM
Start with finding mouse position in world space coordinates:
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
will find the position of the mouse in space, so with that information, you can write
Vector3 direction = (transform.position - worldPosition);
(an algorithm that finds the direction of an object in comparison to another)
Then, turn that into a
Quaternion
usingQuaternion wantedRotation = Quaternion.Euler(direction);
and finally actually set the rotation using some fancy spherical interpolation (s-lerp)
transform.rotation = Quaternion.Slerp(transform.rotation, wantedRotation, turnSpeed)
I think that the slowing at the end looks better than not btw.
TL;DR:
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 direction = (transform.position - worldPosition);
Vector3 wantedRotation = Quaternion.Euler(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, wantedRotation, turnSpeed);
Hey! thank you for this appreciate you dropping by to help! It doesn't quite work as hoped I tried digging around to see if I could get it to function on my project but not much luck, it kind of flip flops all over the place rather than just rotating on the Z axis and I can't quite see how its relating the movement of the cursor. I'm working in 2D, I've tried locking its rotation in the X Y axis but that didn't seem to do anything.
This looks very familiar to a few issues I've run into on previous attempts at getting it to rotate.
This is the approx. set up I have for the scene, the player placeholder is in the middle there starts facing at the Y and I want it to only rotate on the Z so it remains flat to the camera. Not sure how to only apply the rotation to the Z here.
Edit: I managed to get it rotating only on the Z axis but it KEEPS rotating, rather than to the direction of the mouse, then stopping... so, stil not quite there. Oof. I used:
Quaternion wantedRotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(direction.x,direction.y,0));
Oh shoot sorry, the Vector3 wantedRotation should be a Quaternion wantedRotation. It should not rotate on the x and y axis if both 2d objects are in the same plane. Also, sometimes it does go on it's side, so I usually just mess around with the blender export settings until I get the desired effect, but if this is a unity object, I have no idea. Good luck!
Maybe also try Quaternion.LookRotation instead of Quaternion.Euler