# Is it possible to redirect the RayCast of the wheelCollider component?

Hello, I’ve been researching a bit and found some solutions to the problem of the ‘wheelCollider’ component crossing obstacles. But the solution is a bit “too simple” and not very efficient.

Just use the code below on all the wheels of your vehicle.

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

[RequireComponent(typeof(WheelCollider))]
public class Stabilizer : MonoBehaviour { //by Marcos Schultz - www.schultzgames.com

[Range(3,50)]
public int raysNumber = 36;
[Range(45,180)]
public float raysMaxAngle = 135;
public float rayWidth = 0.15f;

WheelCollider _wheelCollider;

void Start () {
_wheelCollider = GetComponent<WheelCollider> ();
}

void FixedUpdate () {
for (int x = 0; x <= raysNumber; x++) {
Quaternion wheelAngle = Quaternion.AngleAxis (_wheelCollider.steerAngle, transform.up);
float angleToRay = x * (raysMaxAngle / raysNumber) + ((180 - raysMaxAngle) / 2);
Vector3 rayDirection = wheelAngle * Quaternion.AngleAxis (angleToRay, transform.right) * transform.forward;
//

//get wheel position and rotation
Vector3 worldPos;
Quaternion worldRot;
_wheelCollider.GetWorldPose (out worldPos, out worldRot);

//raycast center
RaycastHit hitCenter;
if (!hitCenter.transform.IsChildOf (transform.root) && !hitCenter.collider.isTrigger) {
Debug.DrawLine (worldPos, hitCenter.point, Color.red);
}
}

//raycast Right
RaycastHit hitRight;
if(Physics.Raycast(worldPos + (worldRot * Vector3.right) * rayWidth, rayDirection, out hitRight, _wheelCollider.radius)){
if (!hitRight.transform.IsChildOf (transform.root) && !hitRight.collider.isTrigger) {
Debug.DrawLine (worldPos + (worldRot * Vector3.right) * rayWidth, hitRight.point, Color.red);
}
}
Debug.DrawRay(worldPos + (worldRot * Vector3.right) * rayWidth, rayDirection*orgRadius, Color.green);

//raycast Left
RaycastHit hitLeft;
if(Physics.Raycast(worldPos - (worldRot * Vector3.right) * rayWidth, rayDirection, out hitLeft, _wheelCollider.radius)){
if (!hitLeft.transform.IsChildOf (transform.root) && !hitLeft.collider.isTrigger) {
Debug.DrawLine (worldPos - (worldRot * Vector3.right) * rayWidth, hitLeft.point, Color.red);
}
}
Debug.DrawRay(worldPos - (worldRot * Vector3.right) * rayWidth, rayDirection*orgRadius, Color.green);

}
}
}
}
``````

The code will create several RayCast, according to the radius of the wheel, and will find out which is the most distant point of contact. After that, the code will adjust the radius of the wheel according to the distance.

It is possible to see from the image that the code detected the point of greatest distance and adjusted the radius of the wheel accordingly.

But this is a problem because the RayCast of the wheelCollider component always points down. This ends up limiting the situations where this approach is efficient.

So my question is: How to redirect the RayCast of the wheelCollider component? Or, how to make this system better?

Other image:

PhysX allows to configure the suspension travel direction, but that feature is not used in Unity. Suspension (and raycast) is always vertical with respect to the Rigibdody the WheelCollider belongs to.

Recent PhysX versions include new non-blocking queries for handling these situations, but this feature hasn’t been adopted in Unity either:

https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Vehicles.html#wheel-contact-beyond-raycasts

1 Like

There is the NWH asset to solve this problem, and it generates a lot of revenue for Unity. Hardly will they implement a free solution to this problem.

OK, now I really do not know how to soften this problem. I think solutions involving the wheelCollider are useless.