- Home /
Question by
WhaleLuke · Jun 02, 2020 at 03:02 PM ·
gamequaternionmovement scriptgames
How to finish a Quaternion.Euler rotation when you let go of the input?
I am trying to make my character flip like in Paper Mario. When I let go of the input key, the lerping stops, so basically my question is how to "finish" lerping when a key is let go of. This is my flipping/moving code.
void Start() { playerRb = this.GetComponent(); playerTr = this.GetComponent(); }
void FixedUpdate()
{
playerRb.velocity = new Vector2(Mathf.Lerp(0, Input.GetAxis("Horizontal") * moveSpeed, 0.4f), Mathf.Lerp(0, Input.GetAxis("Vertical") * moveSpeed, 0.4f));
if (Input.GetKey(KeyCode.D) && playerTr.rotation.y != 0)
{
PlayerRotator(0);
}
if (Input.GetKey(KeyCode.A) && playerTr.rotation.y != 180)
{
PlayerRotator(180);
}
}
void PlayerRotator(int angle)
{
playerTr.rotation = Quaternion.Lerp(playerTr.rotation, Quaternion.Euler(transform.rotation.x, angle, transform.rotation.z), rotSpeed);
}
Comment
Answer by SteenPetersen · Jun 02, 2020 at 03:02 PM
Your first option would be to do something like this:
[Header("Speed of the character")]
[SerializeField] private float moveSpeed;
[Header("Time taken to complete a full rotation")]
[SerializeField] private float lerpTime;
private bool isFlippingSprite;
private float currentLerpTime;
private int angle;
private Rigidbody2D playerRb;
void Start()
{
playerRb = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (isFlippingSprite)
{
//increment timer once per frame
currentLerpTime += Time.deltaTime;
if (currentLerpTime > lerpTime)
{
currentLerpTime = lerpTime;
}
//lerp!
float perc = currentLerpTime / lerpTime;
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.rotation.x, angle, transform.rotation.z), perc);
// lerp complete
if (perc >= 1)
isFlippingSprite = false;
}
}
void FixedUpdate()
{
playerRb.velocity = new Vector2(Mathf.Lerp(0, Input.GetAxis("Horizontal") * moveSpeed, 0.4f), Mathf.Lerp(0, Input.GetAxis("Vertical") * mo
¨// we are already flipping so disregard this
// call until we are done flipping
if (isFlippingSprite)
return;
if (Input.GetKey(KeyCode.D))
{
PlayerRotator(0);
}
if (Input.GetKey(KeyCode.A))
{
PlayerRotator(180);
}
}
void PlayerRotator(int a)
{
angle = a;
isFlippingSprite = true;
currentLerpTime = 0;
}
The problem here is that you cannot flip while already flipping, to solve that we could do something like this:
[Header("Speed of the character")]
[SerializeField] private float moveSpeed = 10;
[Header("Time taken to complete a full rotation")]
[SerializeField] private float lerpTime = 0.5f;
private bool isFlippingSprite;
private float currentLerpTime;
private int angle;
private Rigidbody2D playerRb;
void Start()
{
playerRb = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (isFlippingSprite)
{
//increment timer once per frame
currentLerpTime += Time.deltaTime;
if (currentLerpTime > lerpTime)
{
currentLerpTime = lerpTime;
}
//lerp!
float perc = currentLerpTime / lerpTime;
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.rotation.x, angle, transform.rotation.z), perc);
// lerp complete
if (perc >= 1)
isFlippingSprite = false;
}
}
void FixedUpdate()
{
playerRb.velocity = new Vector2(Mathf.Lerp(0, Input.GetAxis("Horizontal") * moveSpeed, 0.4f), Mathf.Lerp(0, Input.GetAxis("Vertical") * mo
if (Input.GetKey(KeyCode.D))
{
PlayerRotator(0);
}
if (Input.GetKey(KeyCode.A))
{
PlayerRotator(180);
}
}
void PlayerRotator(int a)
{
if (!isFlippingSprite || currentLerpTime > (lerpTime / 2))
{
angle = a;
isFlippingSprite = true;
currentLerpTime = 0;
}
}
That way we can interrupt the lerp if we are at least halfway through, you can adjust to your liking what to divide by.
result:
ezgifcom-video-to-gif.gif
(445.1 kB)