I’m trying to get an object to stop once it reaches a certain X coordinate. Here is the code that gets it move and that tries to stop it
public Rigidbody rb;
public float sidewaysForce = 500f;
void Start()
{
rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
// Update is called once per frame
void Update()
{
if (rb.position.x == -0.75)
{
rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
}
I’ve tried saving the Time.deltaTime and then using it again for trying to stop it as well but that didn’t work either. I’ve looked plenty of other places but none of them were within the last two years. My Unity version is 2020.3.26f1
Your code wouldn’t work anyway because you’re (for some reason) scaling the sideways forces by the last elapsed frame-delta and then expecting that to be the same during Start and the frame for that single Update. That’s never going to be correct. You don’t need to do that scaling at all.
Why not just set the velocity of the body to zero?
Alright, and how do I set velocity to zero? I’ve tried rb.velocity = Vector3.zero, rb.angularVelocity = Vector3.zero and I’ve tried setting isKinematic to true. None of those have worked. Admittedly of course I got all those ideas from posts over two years old which is why I’m asking here myself
tl;dr
My advice is to just change the == to <
And then disable the component, so that update() will not be called again.
longer version:
This expression unfortunately works in math, but not in programming with floats. The rigidbodies position probably never is exactly -0.75 but maybe -0.7500001 or 0.749999
To get around this, use a sufficiently big “epsilon” like this:
float value = -0.75;
float eps = 0.05f;
if ( Mathf.Abs(rb.position.x - value) < eps) …
The epsilon approach does not work if the rigidbody is too fast for a given epsilon and jumps more than two epsilon between two consecutive frames.
Btw., the Update() method is not the right place for this either. Use FixedUpdate() for this kind of comparison. Fixed update is guaranteed to run always a certain amount of times per second where as Update() might be running way slower or faster, depending on the graphics complexity of your scene.