WheelColliders Slip without end (with planet gravity, custom terrain mesh)
I have been researching, studying, and tweaking the values for hours without any change in effect. The wheels keep sliding sideways and are unable to grip the ground when they have torque.
My setup is unique, with a 3D planet and a large collider:
My vehicle follows the Unity tutorial on the subject. It's just a simple test rectangle with a light weight Rigidbody (1.5). Changing the mass or size has not caused any significant difference.
My wheel collider settings have varied, but do not cause change. For instance:
Forward Friction - Extremum Slip: 0.001 - Extremum Value: 1e+09 - Asymptote Slip: 0.002 - Asymptote Value: 1e+09 - Stiffness: 1
Sideways Friction - Extremum Slip: 0.001 - Extremum Value: 1e+09 - Asymptote Slip: 0.002 - Asymptote Value: 1e+09 - Stiffness: 1
Where I set my values does not make a difference. Even halving the pull of gravity does not have a difference.
Is there a reason the wheel collider settings might be ignored?
To see the effect, watch the video:
How do you handle spherical gravity ? Wheel colliders need enough "pressure" on them to work.
I have an area around the planet where every rigidbody gets a force added towards the center of the planet. Increasing the force of gravity increases the speed at which the wheels slip, making the vehicle "skate" around faster because of the angle at which gravity is applied on uneven terrain. In contrast, a cube is able to bounce and stay stationary because the physics materials handle rough surfaces well.
Hum. How many cars/rigidbodies do you plan to apply gravity to ?
Did you solve it?? I have the same issue with the realistic car controller package.
Answer by UnityCoach · Oct 17, 2018 at 12:21 PM
I did a quick test with the following code. This allows you to test two methods.
Changing gravity settings based on the position of one car on a centre object.
Discard gravity and add G force to as many cars based on their position on center object.
My goal was to tell if the Wheel Collider is somehow using Physics.gravity to do its math. In which case, you couldn't have different gravities in different locations for more than one car.
I've put a 800Kg car on a Sphere of 1000 units diameter, and tested both techniques. I couldn't see much difference in the behaviour of the car. I've tried with a Sphere of 100 units. Same thing.
So it seems it's possible to have cars work with spherical gravity. The problem may be with the Wheel Collider settings.
Hope this helps.
using UnityEngine;
public class GravityCenter : MonoBehaviour
{
public enum GravityMode {PhysicsGravity, AddForce}
[SerializeField] Transform _center;
[SerializeField] float _G = -9.81f;
[SerializeField] GravityMode _mode;
Rigidbody _rigidbody;
void Awake ()
{
_rigidbody = GetComponent<Rigidbody>();
_rigidbody.useGravity = _mode == GravityMode.PhysicsGravity;
Physics.gravity = Vector3.up * _G;
}
void Update ()
{
if (_mode != GravityMode.PhysicsGravity)
return;
Physics.gravity = (_center.position - transform.position).normalized * - _G;
}
void FixedUpdate ()
{
if (_mode != GravityMode.AddForce)
return;
_rigidbody.AddForce((_center.position - transform.position).normalized * - _G, ForceMode.Acceleration);
}
}
Thank you for your thought process. I will test your script when home to check for differences.
I've tried your answer. It gives quite the same result as my own trials, except that when using a vehicle with a large mass (1500 ins$$anonymous$$d of 1.5 as my original), the wheels slip forwards (and not only sideways). The wheel colliders are extremely finicky and provide almost no traction by default.
$$anonymous$$y own script resides on the planet ins$$anonymous$$d of on the vehicle, but performs essentially the same calculation.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Cause any object with a rigidbody to be attracted to the area containing this sphere collider.
/// </summary>
[RequireComponent(typeof(SphereCollider))]
public class Gravity : $$anonymous$$onoBehaviour {
[SerializeField] public float GRAVITY_PULL = .78f;
public static float m_GravityRadius = 1f;
void Awake()
{
m_GravityRadius = GetComponent<SphereCollider>().radius;
}
/// <summary>
/// Attract objects towards an area when they come within the bounds of a collider.
/// This function is on the physics timer so it won't necessarily run every frame.
/// </summary>
/// <param name="other">Any object within reach of gravity's collider</param>
void OnTriggerStay(Collider other)
{
if(other.attachedRigidbody)
{
float gravityIntensity = Vector3.Distance(transform.position, other.transform.position) / m_GravityRadius;
other.attachedRigidbody.AddForce((transform.position - other.transform.position) * gravityIntensity * other.attachedRigidbody.mass * GRAVITY_PULL * Time.smoothDeltaTime);
Debug.DrawRay(other.transform.position, transform.position - other.transform.position);
}
}
}
I have to think about this and come up with a solution that will solve problems for vehicle as well as for airplanes. I know the wheel colliders are calibrated by default for higher values than I have in $$anonymous$$d, so making them work for very small masses may require careful calculations for setup. I may need to set velocity to 0 if the vehicle is traveling at less than a certain speed (simulating breaking and/or static friction, especially where the terrain is not flat). I may also compare sphere colliders, though I really wish there were a cylinder collider, which would solve my problem.
Your answer
Follow this Question
Related Questions
How can I bind this script into the state of my camera? 2 Answers
WheelCollider: Car on boat. Car is pushing boat. CAUSE: WheelCollider (Suspension?) 0 Answers
I need to add a jump function and a gravity function to this script, but I am stuck. 0 Answers
How to make a player instantly reach to a change in gravity? 2 Answers
Object refuses to collide 0 Answers