Issue using wheelColliders around sphere

Hello guys, I hope you’re doing well. I need your help on the following issue.

I aim to create a small prototype where you could drive a car around a sphere. The drive style is semi-realistic, meaning that I will use wheelColliders. For now, the car is only going forward at a reasonable speed. Here’s a quick shot of the issue :

[–>Issue right here <—][1]

As you can see, when the car reaches a certain speed, it loses gravity strength. It is a normal behavior considering physical laws but in this case it’s happening very quickly (way too fast actually…). Here’s some datas to get an idea of what I am doing (wrong?) :


I also tried to apply a LOT of forces to my car to be sure that it stays on the ground but when there is too much forces applied on the wheels, the car is going crazy.

As you can see, I tried also to add joints to force the car to not fly. I actually tried a bunch of various ways to achieve this but it is not precise. Often, I end up with jittery wheel effects or similar behavior that I cannot accept.

Here is the only 2 scripts I use :

sCarManager on the car

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class sCarManager : MonoBehaviour {

    [SerializeField] private WheelCollider[] wcWheels;
    [SerializeField] private float fMotorTorque;
    private float fCurrentSpeed;
    private float fInitialSpringStrenght;
    private sGravityManager sGM;
    private SpringJoint sjJoint;
    private Rigidbody rbRigid;

    public static sCarManager instance = null;

    private void Awake() {

        if (!instance) { instance = this; }


    private void Start() {

        //Initialize script type variables
        sGM = sGravityManager.instance;
        //Initialize the array at 4 and get the wheels from the car
        wcWheels = new WheelCollider[4];
        GameObject goWheelsParent = GameObject.FindGameObjectWithTag("WheelColliders");
        for (int i = 0; i < 4; i++) {
            //Get each wheelCollider from the car
            wcWheels *= goWheelsParent.transform.GetChild(i).GetComponent<WheelCollider>();*

//Initialization of Rigidbody
rbRigid = gameObject.GetComponent();
//Initialization of variable joint
sjJoint = gameObject.GetComponent();
fInitialSpringStrenght = sjJoint.spring;


//Called every fixed frame
public void FixedUpdate() {

//Apply a torque to all wheels
ApplyMotorTorque(wcWheels, fMotorTorque);

//Get the current speed of the car
fCurrentSpeed = rbRigid.velocity.magnitude;
//Increase joint strenght based on speed
sjJoint.spring = fCurrentSpeed * fInitialSpringStrenght;


//Apply torque to specific wheels
private void ApplyMotorTorque(WheelCollider[] wcs, float trq) {

for(int i = 0; i < 4; i++) {
wcs*.motorTorque = trq;*


sGravityManager on the planet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class sGravityManager : MonoBehaviour {

private sCarManager sCM;
private Rigidbody rbCar;
private Rigidbody rbPlanet;
private Transform trCOM;
public Vector3 v3GravityForceToApply;
//Instance of this script
public static sGravityManager instance = null;

//Launch the very first frame
private void Awake() {

if(!instance) { instance = this; }


private void Start() {

//Initialize script variables
sCM = sCarManager.instance;
//Increase fixed timestep pace
Time.fixedDeltaTime = 0.01f;
//Get the car and planet RigidBodys
rbCar = GameObject.FindGameObjectWithTag(“Car”).GetComponent();
rbPlanet = transform.GetComponent();
//Initialize transforms and script variables
trCOM = GameObject.FindGameObjectWithTag(“COM”).transform;


private void FixedUpdate() {

#region Constant gravity force
//Get gravity force based on car and planet positions
v3GravityForceToApply = GravitySimulation(rbCar, rbPlanet);
//Apply the force to the RigidBody


//Method returning the direction in which the car is being pulled
private Vector3 GravitySimulation(Rigidbody rbc, Rigidbody rbp) {

//rbc → RigidBodyCar and rbp → RigidBodyPlanet
Vector3 v3Direction = rbp.position - trCOM.position;
float fDistance = v3Direction.magnitude;

float fForceMagnitude = (rbc.mass * rbp.mass) / Mathf.Pow(fDistance, 2);
Vector3 v3Force = v3Direction.normalized * fForceMagnitude;

return (v3Force);
So, do I need to calculate a force to apply, based on car’s velocity, at each frame? Did I miss another inventive way to ground the car for a bit longer? What are your thoughts in this situation guys?
(For those who will suggest to not use wheelColliders, this is not related to this topic. Thank you for your understanding. No offense.)
Thanks for the time spent reading this post, it is a long one!
_[1]: SENDEYO, Free image and photo host. Transfer and share PDF, ZIP, mp3, mp4 files


Gravity force lingers towards the direction when the first time it applied. If you can, tilt whole velocity towards center of the sphere before applying new one. ( as you mentioned )

 float magnitude =  rbc.velocity.magnitude;
 float degToRadian = (Mathf.PI / 180);
 float x_rotation  = transform.eulerAngles.x;
 float x_rotation_in_radian = x_rotation * degToRadian;
 rbc.velocity = new Vector3(0, magnitude * Mathf.sin( x_rotation_in_radian  ), Mathf.cos( x_rotation_in_radian ) );

Documentation suggest to not modify velocity directly, b/c unrealistic physics behavior, its your call.

Or you can make car body fixed and make the sphere rotate under the wheels ? Like the first car race games, road moves. Then rotate camera reverse of the sphere’s rotation for gravity illusion.