0
\$\begingroup\$

So I am trying to implement a car controller script in Unity were the WheelTransform position and rotation is set with every update as the same as the WheelCollider position and rotation, it all works fine except for one thing: when translating the WheelTransform, if the car goes slowly, WheelTransform translates as expected, but when the car goes faster, there's a clear offset between the WheelTransform position and the actual position of WheelCollider. Here's the code were WheelTransform position and rotation is set as the same as the WheelCollider position and rotation:

private void UpdateWheels()
    {
        UpdateWheelPos(frontLeftWheelCollider, frontLeftWheelTransform);
        UpdateWheelPos(frontRightWheelCollider, frontRightWheelTransform);
        UpdateWheelPos(rearLeftWheelCollider, rearLeftWheelTransform);
        UpdateWheelPos(rearRightWheelCollider, rearRightWheelTransform);
    }

    private void UpdateWheelPos(WheelCollider wheelCollider, Transform trans)
    {
        Vector3 pos;
        Quaternion rot;
        wheelCollider.GetWorldPose(out pos, out rot);
        trans.rotation = rot;
        trans.position = pos;
    }

Every single one of the car controller scripts I've found and tried use the same code for this section, I have also tried with 2d sprites without any colliders as WheelTransform but neither the scripts or changing WheelTransform solved the problem. Thanks in advance for the help.

\$\endgroup\$
4
  • \$\begingroup\$ Can you show us how you've configured the visual objects referenced by the wheel transforms? A screenshot of the offset you're observing could also help us diagnose the cause. \$\endgroup\$ – DMGregory Mar 8 at 16:05
  • \$\begingroup\$ Are you calling UpdateWheels() from an Update() function? Try calling it from LateUpdate() instead. \$\endgroup\$ – Kevin Mar 8 at 19:17
  • \$\begingroup\$ Kevin's solution fixed the issue, thanks \$\endgroup\$ – user14791290 Mar 8 at 19:44
  • \$\begingroup\$ @user14791290 Great, I've posted it as an answer. \$\endgroup\$ – Kevin Mar 8 at 23:28
0
\$\begingroup\$

This type of issue can occur if two different components are updating an object's position during the frame Update cycle. In this case, WheelCollider might be recalculating the pose during Update().

The specific order that Update() is called on scripts is undefined (and should be considered random) unless you've explicitly set a Script Execution Order.

If your script is calling UpdateWheels() from an Update() function, you would see synchronization issues if your script happens to be updating before WheelCollider each update. In other words, your script moves the transform to match the pose, then the pose changes, and then the frame is rendered with your transform no longer matching the pose.

One way to fix this is to edit the Script Execution Order, but I recommend never editing the execution order unless you absolutely have to, because it is a sort of hacky solution (and the UI for changing it in the Unity Editor is atrocious). In this case, you can instead change your script so that UpdateWheels() is called from LateUpdate(); that will ensure your code always runs after the WheelCollider has already updated its pose.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.