Unity making a weird bug

Hello,
I have been experimenting with 3D movement since I am a beginner and I have found something weird.
If I don’t "implement’ the rb.AddForce() line, the calculation goes good, but as soon as I include that line of code, the calculation messes up horribly.
It also doesn’t matter if I put the Calc() in Update or FixedUpdate, the result is the same.

Here’s the code:

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] private float maxSpeed;
    [SerializeField] private float acceleration;
    [SerializeField] private float deceleration;

    [SerializeField] private Vector3 moveCalc;

    private Vector3 moveInput;

    private Rigidbody rb;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Start()
    {
        rb.freezeRotation = true;
    }

    private void Update()
    {
        moveInput.x = Input.GetAxisRaw("Horizontal");
        moveInput.z = Input.GetAxisRaw("Vertical");

        Calculate();
    }

    private void FixedUpdate()
    {
        rb.AddForce(transform.right * moveCalc.x + transform.forward * moveCalc.z);
    }

    private void Calculate()
    {
        Vector3 max = moveInput.normalized * maxSpeed;

        Vector3 diff = max - rb.velocity;

        Vector3 accel = new(Mathf.Abs(max.x) > .1f ? acceleration : deceleration, 0, Mathf.Abs(max.z) > .1f ? acceleration : deceleration);

        moveCalc = new(diff.x * accel.x, 0f, diff.z * accel.z);
    }
}

“Messes up horribly” how?

The character starts to move in zig zag patterns and spinning, rotation is frozen, i dont know what is going on

Well, hurry and find out!!

Make a blank scene, make a fresh character, drop this script on it, hook everything up and run it.

Does it work? If so, go back to what you had before and figure out what’s different.

If it doesn’t work then that means… time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

bruh its not a code error, without the addforce the calculation works, with it it breaks, why does addforce make the calculations incorrect

This isn’t intended to start an argument but of course it is a code error.

The first rule of software development is “it is probably your fault”. It could be due to a misunderstanding of how things work but one can’t suspect that nobody has been able to AddForce to a rigid body.

There is nothing in the code you’ve shown that reveals what the values are (like logging the values as a sanity check). I don’t know in what order your AddForce calculation is being executed but I never leave equations to chance. Parentheses to insure order are free to use.

1 Like

Do you understand that the Calculate() method is simply performing a P filter control operation?

Your description of the problem sounds like your P filter gain is way too high.

Have you debugged it to see what values are going in and how it responds?

If you want to move up the food chain of controller logic, you’re welcome to integrate the next step, a PD Filter, in order to replace your P filter.

What’s the intended purpose of that code? What kind of movement are you trying to replicate?

There are multiple modes for that method. By default it’s choosing Force but you may have wanted Acceleration.

Well, I can see an issue here. Specifically this:

Those two lines don’t make sense as your moveInput is supposed to be in local space but then you subtract a world space vector, namely the velocity of the rigidbody. So you’re mixing coordinate spaces here. Also AddForce has an optional “Space” argument where you can select if you want to apply a world space or local space force. You can use AddRelativeForce to apply a local space force.

So you have to decide if your moveCalc should be in local space or world space. Everything else in your code seems to imply that you intend to use local space except for the velocity subtraction. So either transform the velocity into local space (InverseTransformDirection) or calculate your moveCalc and accel stuff in worldspace.

I think you may be confusing the AddForce arguments with transform.Translate’s arguments. AddForce doesn’t have a Space argument. Although we can use the underused AddRelativeForce if we want to move a rigidbody in local space.

1 Like

Yes, you’re right :slight_smile: AddRelativeForce. It’s been a while since I used any physics in Unity.