Predict rigidbody position from Addforce ForceMode.VelocityChange 3D

Trying to match a rigidbody position to another. I can match it exactly by adjusting the velocity directly. But, the same does not work with Addforce ForceMode.VelocityChange. The positions seem to be off in the beginning and end which leads me to believe there is some type of acceleration and deceleration involved. Anyone have any thoughts or pointers?

private void FixedUpdate()
    {
        // works. Positions match exactly
        //ChangeVelocityDirectly();
       
        // does not work
        AddForce();
    }

    void AddForce()
    {
        Vector3 startingVelocity = objectToFollow.GetComponent<Rigidbody>().velocity;
        float fixedDelta = Time.deltaTime;

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        Vector3 vel = new Vector3(x, 0, y);
        Vector3 moveDirection = transform.TransformDirection(vel);
        moveDirection = moveDirection * Speed;

        Vector3 forceToAdd = moveDirection - startingVelocity;
        objectToFollow.GetComponent<Rigidbody>().AddForce(forceToAdd, ForceMode.VelocityChange);

        // Seems to be off during beginning and end. Looks like some type of acceleration and deceleration
        Vector3 predictedPosition = objectToFollow.position + (objectToFollow.GetComponent<Rigidbody>().velocity * fixedDelta);

        // Matching Rigidbody
        Vector3 displacement = predictedPosition - followingRB.position;
        Vector3 initV = followingRB.velocity;

        forceToAdd = displacement / fixedDelta - initV;
        followingRB.AddForce(forceToAdd, ForceMode.VelocityChange);


        PhysicsScene.Simulate(Time.fixedDeltaTime);

        if ((objectToFollow.position - followingRB.position).magnitude > 0)
        {
            Debug.Log("<color=cyan>" + objectToFollow.position.ToString("F9") + " " + followingRB.position.ToString("F9") + "</color>");
        }
        else
        {
            Debug.Log("<color=yellow>" + objectToFollow.position.ToString("F9") + " " + followingRB.position.ToString("F9") + "</color>");
        }
    }

    void ChangeVelocityDirectly()
    {
        float fixedDelta = Time.deltaTime;

        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");
        Vector3 vel = new Vector3(x, 0, y);
        Vector3 moveDirection = objectToFollow.TransformDirection(vel);
        moveDirection = moveDirection * Speed;

        objectToFollow.GetComponent<Rigidbody>().velocity = moveDirection;

        Vector3 predictedPosition = objectToFollow.position + (objectToFollow.GetComponent<Rigidbody>().velocity * fixedDelta);

        // Matching Rigidbody
        Vector3 displacement = (predictedPosition - followingRB.position) / fixedDelta;

        followingRB.velocity = displacement;


        PhysicsScene.Simulate(Time.fixedDeltaTime);

        if ((objectToFollow.position - followingRB.position).magnitude > 0)
        {
            Debug.Log("<color=cyan>" + objectToFollow.position.ToString("F9") + " " + followingRB.position.ToString("F9") + "</color>");
        }
        else
        {
            Debug.Log("<color=yellow>" + objectToFollow.position.ToString("F9") + " " + followingRB.position.ToString("F9") + "</color>");
        }
    }

different masses / friction (physic materials) ?

Same mass. Identical rigidbody. I don’t believe mass is included in the velocitychange.

The solution in this case is not to use the Rigidbody velocity for prediction, but the move direction * delta. Rigidbody.velocity will be Vector3.zero until after there is movement so the initial frame of movement will predict 0 * delta = 0.

Thanks for the reply

Your predictedPosition will lag one frame for sure since AddForce will be added during physics calculations.

Is PhysicsScene.Simulate(Time.fixedDeltaTime); for debugging purpose ?

PhysicsScene.Simulate(Time.fixedDeltaTime) is where the physics simulation should happen. In this scenario, Physics.autoSimulation is off.

The debug after should be the result of the calculations.