- Home /
My sprite only flips when crossing the center of the screen.
I wrote this little code for my game which uses a move to mouseclick movement system. Now I want the sprite to rotate to the direction hes moving. I only want this to happen to his right and left. I got it working kinda but now it only flips when its moving to the other side of the screen. This is my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 1.5f;
public Vector3 targetPosition;
public Animator animator;
private bool isMoving = false;
private void Update()
{
if (Input.GetMouseButton(0))
{
SetTargetPosition();
}
if (isMoving)
{
Move();
animator.SetInteger("States", 1);
} else
{
animator.SetInteger("States", 0);
}
}
void SetTargetPosition()
{
targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPosition.z = transform.position.z;
isMoving = true;
}
void Move()
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetPosition), 0.15F);
Vector2 direction = new Vector2(
targetPosition.x - transform.rotation.x, 0);
transform.right = direction;
if (transform.position == targetPosition)
{
isMoving = false;
}
}
}
First of all, you're using Slerp wrong, its like any lerp, the modifier float only ranges between 0 and 1.0, so what this means is that lerping by .15f is going to move it exactly 15% of the total distance every frame, cumulatively. So lets say distance of rotation starts at 100 degrees, so one frame passes, and now theres 85 degrees left, a second frame passes and now theres 72.25 degrees left, third frame passes and its 61.4125 degrees. $$anonymous$$y point being that it's going to get slower as it gets closer to the actual destination. Which is not how lerping is supposed to work. Lerping should done "over time" Now you can still accomplish this through Slerp, but I just want to make sure you know what's actually happening here. Second factor, you should never do any "over time" function without scaling it by time itself, in most cases that means multiplying our movement amount by Time.deltaTIme. Which you already did for actual movement, not sure why you skipped it on rotation.
In reality you should be using Quaternion.RotateTowards, because it was actually mode for this.
Also I'm pretty sure LookRotation uses Vector3 forward, which on sprites forward is either Vector2.right or Vector2.up. So there's a lot going on here that you may want to fix. Which it's obvious you're aware of this because you switch the position with the x rotation, but I think this might be where you're getting some of your issue. You can't rotate an object AND THEN set one of it's rotation axis in the following line of code, what this does, is completely throws off the actual rotation because for the first frame it tries to rotate towards that, then you assign a new transform.right axis, and this sets the objects rotation to that. So next frame it's attempting to rotate from a completely different angle. Does that make sense? Either rotate the object, or rotate the axis, not both.
EDIT I Should point out, if you wanted to rotate an axis you do
transform.right = Vector3.$$anonymous$$oveTowards(transform.right, (targetPos - transform.position).normalized, rotationSpeed * Time.deltaTIme);
Alright thanks for your reply! I changed my scripts and it runs a lot smoother now. The only problem I still have is that the sprite only flips when passing the center of the screen. Like there is like this imaginary line in the middle of the screen where the sprite only flips when passing that line. I dont know if this has anything to do with the camera or the ScreenToWorldPoint.
Answer by RobAnthem · Mar 06, 2020 at 11:40 PM
Sorry, meant to reply sooner. The actual problem here is your line
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetPosition), 0.15F);
Quaternion.LookRotation takes in a direction and outputs a rotation, you're simply giving it a position, which is only half a direction. So you want to do this.
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetPosition - transform.position), rotationSpeed * Time.deltaTime);