- Home /
RigidBody velocity ends with weird floating value, when axis key is released.
In the image provided, you can see that the velocity of the rigidbody turns negative for a few frames then down to zero. I would like to know why it does such, and how it can be avoided.
![using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private Rigidbody2D myRB;
private Animator myAnim;
private float axisX;
[SerializeField][Range(0.1f, 10.0f)] private float moveSpeed = 5.0f;
void Start()
{
myRB = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>();
}
void Update()
{
Debug.Log(myRB.velocity.x);
axisX = Input.GetAxis("Horizontal");
FlipSprite();
}
private void FixedUpdate()
{
Run();
}
private void Run()
{
Vector2 playerVelocity = new Vector2(axisX * moveSpeed, myRB.velocity.y);
myRB.velocity = playerVelocity;
}
private void FlipSprite()
{
bool hasHorizontalSpeed = Mathf.Abs(myRB.velocity.x) > Mathf.Epsilon;
if (hasHorizontalSpeed)
{
transform.localScale = new Vector2(Mathf.Sign(myRB.velocity.x), 1f);
}
}
}][1]
[1]: /storage/temp/162996-tilevania.png
Answer by Captain_Pineapple · Jul 08, 2020 at 09:21 PM
Hey there,
the weird value you got there is something like -1.5E-14. So -1.5 devided by (10^14). which is 0. At least in the world of floating point precision. When handling floats you can never be 100% certain that if you calculate 100/10 it will actually be 10 in the end. The result might also be 9.999999999.... or 10.000000000001. There are certain imprecisions that can not be avoided in floating point mathematics. Thus it can also lead to "negative" numbers.
That said - how do you avoid that? -> You don't. There is just no way to ensure that this does not happen.
Answer by Ronako · Feb 07 at 12:59 AM
For anyone still having issues with this and happens across this article, here is my solution to this weird problem. By creating a new variable lastInputValue, and setting it equal to moveInput.x when moveInput is not zero (can probably do this by checking moveInput.x != 0, or the way I have shown, with moveInput != Vector2.zero), we can get rid of any floating point inaccuracies by using this lastInputValue inside our FlipSprite.
float lastInputValue = 1f;
void OnMove(InputValue value)
{
moveInput = value.Get<Vector2>();
if (moveInput != Vector2.zero)
{
lastInputValue = moveInput.x;
}
}
void OnJump(InputValue value)
{
if (value.isPressed && collider.IsTouchingLayers(LayerMask.GetMask("Ground")))
{
rigidBody.velocity += new Vector2(0f, jumpSpeed * Time.fixedDeltaTime);
}
}
void FlipSprite()
{
playerHasHorizontalSpeed = Mathf.Abs(rigidBody.velocity.x) > Mathf.Epsilon; // Epsilon is technically better to use than 0 for comparing.
if (playerHasHorizontalSpeed)
{
transform.localScale = new Vector2(Mathf.Sign(lastInputValue), 1f);
}
}
Good luck everyone!
Your answer
Follow this Question
Related Questions
Set Object Rotation based on Collision (2D) 0 Answers
how to make an 2d object move the direction its facing using rigidbody2d.velcoity 1 Answer
Unpausing While Keeping Values 0 Answers
Adding speed relative to move vector (Rigidbody2D) 1 Answer
Need help for my Arkanoid-like game. i got problem to make my ball reflects on the wall 1 Answer