How To Exit Collider Hell
tl;dr: things break at high speeds
This is true everywhere from physics to software development. In this case, the car would clip into the ground while taking a sharp turn. This would ruin runs on Desert Speedway and Turbine Climb, and in some cases Rock Loop I. Adding more loops for the Orange Tracks update meant the car was getting knocked off the high speed loops in a way that was unacceptable for an actual commercial product.
What was causing it, and how do you fix it? The stupidly simple fix will surprise you.
Here are some of the things I tried:
- changing the car's rigidbody collision detection mode from discrete to continuous to continuous speculative
- shortening the length of the physics simulation timestep
- lowering the max depenetration velocity of overlapping colliders
- changing the slightly pointy car mesh collider to some insane bullshit made of overlapping rounded cylinder colliders (these could get the track wall wedged in between them which looked to the player like the car clipped into the wall and got stuck)
- hugely increasing the subdivision count of the collision mesh for the road (bad for memory and application performance)
- making the road collision mesh a 2d surface with just the top edge instead of a full 3d object (this is why you're able to jam yourself underneath it to get that cool cut on Hydroplane)
- adding zero-friction, zero-bounce sphere colliders slightly smaller than the wheel radius to the wheels if the suspension force wasn't working enough (bordering on the verge of insane hacks and immediately reverted)
Here's what actually fixed it:
- quadrupling the spring strength of the car's suspension
While debugging and playtesting, I pulled up the telemetry I made when I was first writing the suspension code and realized the suspension compression ratio was peaking at a higher number than I expected on tracks where the road took a concave curve.
A suspension compression ratio of 0 means there's no compression on the car springs, and a ratio of 1 means the suspension is bottoming out. On loops, it was at 4.5. The suspension was bottoming out, and then some. And then some. The colliders I had on the car body were scraping on the road because of the weak springs and clipping into it, and then getting rejected by the fact that there were two solid objects occupying the same space, which made the car jump into the air and ruin a line.
If you think about this at all, it makes complete sense. A car taking Hot Wheels ass loops at 180 MPH will need stronger springs than a car driving at 10mph on a flat plane over speed bumps, which is all I was doing when I was setting the suspension numbers while writing/playtesting the suspension system very early on in the game's development. The issue didn't become apparent until I started making tracks that actually pushed the system to its limits.
Anyway, that fixed it. There was another issue with splines on long tracks being low-resolution so it felt like the tracks were lower-poly than they actually were, but I found and fixed it in the span of an update so you guys didn't get hit by it. Thanks for reading! I can share a writeup of my wheel code in another post if there's interest.
Why not just use Unity's wheel collider component, you ask? Multiple reasons:
- It's built for more realistic racing games and uses a Pacejka slip curve, which breaks my steering angle-based TCS implementation. I'm not smart enough to know how to optimize a steer angle with changing horizontal velocity and I can't do it without seeing the wheel source code, which isn't available anyway.
- The suspension raycasts are treated as a single vertical raycast instead of a half-moon fan of raycasts, which means that there's no gradual transition when the wheel goes over a ledge or bump. It just snaps to the distance of whatever's directly under the wheel, which looks bad at low speeds.
- The wheel has mass, which yanks on the connected rigidbody in weird ways.
- The wheels apply drive force to the ground at their contact patch, which is realistic but gets unpredictable and annoying to calculate. I add drive force from the wheels together and apply it at the center of each axle, which is way more arcadey but also allows for under/oversteer when drifting.
I might talk about my TCS code in another post, because it's kinda niche but fits well with the rest of the car dynamics I designed.
Get NEODRIVE
NEODRIVE
time attack high-skill arcade racer
Status | Prototype |
Author | sevencrane |
Genre | Racing, Action |
Tags | Low-poly, Singleplayer |
Accessibility | Configurable controls |
More posts
- 0.7.3 - Security3 days ago
- 0.7.2 - UI Polish4 days ago
- 0.7.0 - Orange Tracks5 days ago
- 0.6.0 - Hydroplane11 days ago
- 0.5.1 - Tunnels29 days ago
- 0.5 - Better physics, more tracks, new wheels, more51 days ago
- 3D tracks, wheel support78 days ago
- Ghosts82 days ago
Comments
Log in with itch.io to leave a comment.
I love this post, just my kind of litterature.
I'd love to see a screenshot of the cylinder collider mess, if it's still accessible, kinda like topology gore but in volume instead.
I've never liked the wheel collider component, even if I only tampered with it on a surface level. It's just the kind of thing that makes it "so much simpler" by being bloated with features and introduces so many undocumented problems and uneditable source.
Wait there's a hemisphere raycast? Or do you have a method that sends an array of them? Or maybe it's 3 raycasts and you interpolate the height with a circular ramp?
"Oh but what if your car rolls on rigid bodies, if it doesn't apply force it won't be realistic and-" Ok but what if the game doesn't have or need either? Sorry, more Wheel Collider rant lol. It's one of those systems that just feels like it's taking the decisions instead of the actual dev. It was a reoccurring sentiment I had working with many builtin systems of Unreal Engine.
This sounds similar to a problem that I had in a similar project. I didn't think to increase the supsension strength, although my suspension code was pretty bad/unstable - setting the strength too high meant that my car wouldn't be able to stand still without randomly bouncing into infinity. I might try revisiting it and using that approach whenever I get back around to it.
The way I 'fixed' it in my game was by adding a secondary somewhat thin box collider underneath my real collider which had a different ice-like physics material that has slip set to 1 (max) and bounce set to 0. Should my suspension give out completely, the car->road contact then has 0 consequences
That's interesting. If your math for the springs is good, you might need to play with the damping settings instead, because at higher suspension values you get a narrower range of working damping values. I think my spring strength is internally set to 1500 and the damping value is 100. Any much more or less than 100 damping makes the suspension unable to sit still.
Also yes, I did the exact same thing - a sideways capsule under the front bumper with 0 bounce/friction, but it didn't solve my issues because the car was going fast enough that it'd clip into the track between timesteps and get spat out.