How to remove jittering from rigidbody interpolation?

Hello everyone,

I am using Rigibody to apply forces to my game objects to get natural movements. I am calculating a lot of things (even non physics) in the FixedUpdate instead of the Update because I noticed a lot of visual issues like jittering when I separate it.

Someone on another post told me to use interpolation in the rigid body, which seemed like the perfect idea, but it got even worse.

It adds jitter to the camera, as mentioned in the Unity documentation, and there is no mention of how to fix it.

I mean impossible to say without seeing the code.

In your original post you weren’t using physics. You were just assigning the position of the transform, completely bypassing the physics engine.

I don’t really know which part of the code you would need. I don’t even know where the problem is coming from. What I can show you is the following:

image

The pod and the engines have a rigidbody attached to them.

To move the engines, I apply a force on them in a script called “Thruster”:

rb.AddForce(force.normalized * magnitude);

I am calculating the center position of the engines in another script called “EngineManager”:

public class EnginesManager : MonoBehaviour
{
    [SerializeField] EngineController[] engines;

    #region MonoBehaviour

    void Awake()
    {
        UpdateTransform();
        InitializeEngines();
    }

    void Update()
    {
        UpdateTransform();
        StabilizeYRotation();
    }

    void FixedUpdate()
    {
        AttractEngines();
    }

    #endregion

    void InitializeEngines()
    {
        foreach (var engine in engines)
            engine.SetDistanceFromCenter(transform.position);
    }

    void UpdateTransform()
    {
        transform.position = CalculatePosition();
        transform.rotation = CalculateRotation();
    }

    void AttractEngines()
    {
        foreach (var engine in engines)
            engine.AttractTo(transform.position, transform.rotation);
    }

    void StabilizeYRotation()
    {
        foreach (var engine in engines)
            engine.RotateY(transform.rotation.eulerAngles.y);
    }

    #region Calculate

    Vector3 CalculatePosition()
    {
        Vector3 center = Vector3.zero;
        foreach (var engine in engines)
            center += engine.transform.position;
        return center / engines.Length;
    }

    Quaternion CalculateRotation()
    {
        Vector3 eulerAngles = Vector3.zero;
        foreach (var engine in engines)
            eulerAngles += engine.transform.eulerAngles.To180();
        return Quaternion.Euler(eulerAngles / engines.Length);
    }

    #endregion
}

In the Pod, I have a 3 virtual cameras for different points of view during the race.

Here is the result when Interpolate = None:

Normal

When I set Interpolate = Interpolate, it gets really messy.

Lag

As you can see there is a big difference.

I would like to correct that because I am working on the cable system and it is very jittering too even with no interpolation. I guess it is because of that but I am not sure.

I was calculating this position from two game objects using physics to move.

Point still stands. Move the engines via the rigidbody. Interpolation does nothing if you completely bypass it and position the transform directly.

I thought the interpolation was for the transform to be updated smoothly in the Update instead of each FixedUpdate.

Sure, if you weren’t stomping over the rigidbody and just controlling the transform yourself.

This is Unity physics 101. If you want the rigidbody to do it’s thing, you do not control the transform directly. I cannot state this enough.

Oh ok, I agree with that. I was talking about the engines and the pod. I know that for the engine manager I am not using a rigidbody and just calculating the centre position.

But is this related to the fact that when interpolation is turned on, everything does not work as well as when it is turned off?

Make the cameras a child of the chariot/pod and be sure to move the pod also with AddForce. Or if you need to keep the cameras separate then make them track the pod’s transform.position and not the pod’s rigidbody.position.

I use cinemachine, the virtual cameras are children of the pod and the pod is moved using AddForce too like the engines.

I don’t think you want your camera, virtual or otherwise, to be directly parented to physics objects. They should be separate and scripted to follow the rigidbody in LateUpdate to smooth out the rigidbody movement.

But cinemachine should already do that right?

I’ve never tried cinemachine but I assume it’s purpose is for tracking moving objects and so it may be redundant using it for a camera that’s a child of another object. Try seeing what happens if you remove cinemachine.

I already tried and I have the same result. But I placed the camera as child of the pod. The thing is, when I look at the module in the scene, nothing is jittering, only when I am in the game view.

You’re assuming again. You shouldn’t assume in game dev.

It’s also Unity 101 that camera movement be handled in LateUpdate.

What is Unity 101?

Cinemachine has been made for that, interpolating the camera position between virtual cameras.

As in general Unity things that should be learnt in your early days of learning Unity.

A virtual camera can’t bypass the fact that when it’s a child of a rigidbody, it is not moving in a smooth manner. Virtual cameras should be set to have a target so they can follow the target in a properly configured manner.

Looking at my own set up in a current project, make the virtual camera a sibling, set the target to the pod (or an object in the correct position, you get the idea), set the body to framing transposer, and wind the soft-zone x and y down to zero.

I just tried to make the virtual camera follow the pod but with a damping different than 0, I have jittering too.

Here are the settings:

I’m new to Unity so I recognize that jitter from my own games. As has been mentioned, it’s because you’re changing the transform directly. Look into using Rigidbody.Move, as this won’t be the last issue it’ll give you if you keep altering the transform.

Maybe I miss explained the problem.

I am not changing the transform of my engines, they are diven by the rigidbody by applying force to them using rb.AddForce. So I guess, no issue on this side.

I need some information about the center position of the engines and the average rotation which is calculated like so:

Vector3 CalculatePosition()
{
    Vector3 center = Vector3.zero;
    foreach (var engine in engines)
        center += engine.transform.position;
    return center / engines.Length;
}

Quaternion CalculateRotation()
{
    Vector3 eulerAngles = Vector3.zero;
    foreach (var engine in engines)
        eulerAngles += engine.transform.eulerAngles.To180();
    return Quaternion.Euler(eulerAngles / engines.Length);
}

Very simple too.

This transform that represents the center position and mean rotation is called the engine manager.

This engine manager is just here to give that position to the pod then the pod is being attracted to this position. Attracted with the use of another rb.AddForce.

I tried everything, I removed all the unecessary things on my engines and pod, I tried to move some code from FixedUpdate to Update and vice versa and more. I also tried to move the pod with the rb.Move() and did the same for the engine manager but the result is the same. When interpolate = interpolate and not None, the camera is jittering.

I also tried to not use cinemachine, use damping, use transpose, put as a child or or. Nothing changed the result.

If you are interested, I can give you a simple version of this project to let check by yourself.

That is perplexing. I’d be interested in taking a look at it.