I'm an ex-long time "AAA" game programmer, now solo indie developer making GearBlocks, a game all about creative building, interactive machines, and gears - lots of gears!

Report RSS New demo build 0.5.6628

Posted by on

Time for another long overdue demo release, and an update on what I've been working on recently!

Linker tool

After the last update where I talked about the pulleys and linker tool that I was working on, I have since completed the first pass implementation of the linker tool, and links between pulleys can now be set up by the player (rather than being hard coded).

However, the linker tool goes far beyond just pulleys and belts, my intention is that it'll be a general way to associate various part behaviours together (e.g. batteries, switches, motors, and eventually, more advanced control systems), and this introduces the one major wrinkle I still have to figure out.

The thing is, parts can potentially have multiple behaviours associated with them, which means in theory there could be multiple links between two parts. I need to decide whether to either prevent multiple links (and in which case, how to do this in a way that makes most sense), or allow for them (in which case, how to represent them to the player via the UI, and if the player should have the ability to create links between individual part behaviours).

I also still need to add UI indicators, both to show those links already existing, and a link as it's being added or removed (right now I'm still using debug lines).

At this point I decided to have a break and work on some other stuff instead, but I will be getting back to the linker tool very soon.

Third person camera

I've now added third person cameras to the game, both for when the player is walking around, and for when they're seated. I debated doing this for a while actually, because I don't currently have a proper player model, but I finally relented mainly because it's so much fun to be able to see vehicles from the outside as you're driving around!

The player models and animations I'm using are just placeholders that I put in ages ago for the prototype multi-player mode. Of course this now forces the issue - I now have to decide what the player character(s) should look like, as well as source the models for them, and put in better animations. Looks like I've just created a load of more work for myself!

Wheel physics revisited

OK, this is the big one. It wasn't supposed to be a big deal, but ended up taking several weeks to sort out! I wanted to build on the "proving ground" aspect of the desert map in the game, so I added some bumps and ramps (for testing vehicle suspension and so on). However this highlighted a significant problem with the wheel physics.

Let's briefly recap how the wheels worked up until this point. First the wheel finds where it contacts the ground, by firing a Raycast towards it (perpendicular to its rotational axis) to find a contact position and normal. Then, it uses a ConfigurableJoint connected to the wheel's rigidbody, that every update gets repositioned using the contact data, and has a linear limit set up to provide the collision response. If you're interested, I did a detailed write up on this a while back: Tmblr.co

Using a Raycast to find the ground contact point was acceptable on terrain with a smoothly changing gradient, but fails once other collision shapes besides the base terrain are introduced (such as boxes, spheres, etc.) for the wheels to roll over.

You can see here in this example that the Raycast can't "see" the box, so the wheel inter-penetrates it. But worse, if the wheel continues to move in the direction shown, the Raycast will eventually hit the box, causing the contact point's height to change instantaneously, pushing the wheel up with a large impulse.

So I wanted to come up with a new technique to find the contact point that would meet some important criteria:-

  1. It should ensure that the contact point's position changes smoothly with no discontinuities.
  2. It should allow the wheel to accurately roll over box, capsule, and sphere colliders.
  3. It should not change the wheel's behaviour on the base terrain (this can be very sensitive, particularly for vehicles traveling at high velocities).
  4. It should not incur any additional performance cost over the existing solution.

I experimented with many alternative ideas, including using a bunch of BoxCasts to approximate a cylindrical shape, but everything I tried failed one or more of these criteria. That is, until I eventually settled on using a single CapsuleCast in the downward direction, whose radius is the same as the wheel's.

However this clearly has similar problems to just simply using a CapsuleCollider for the wheel. For example, if the wheel is tilted to one side relative to the ground, we get a contact point outside of the wheel, coming from one of the capsule's "end caps". To get around this, I effectively clamp the contact point to be within the wheel's outer rim, as shown in the diagram below (this time viewing the wheel end on):-

This assumes that the terrain's gradient doesn't change too much between the found contact point and the final clamped point!

Another problem is shown here, where the CapsuleCast would find a contact point on the box in this example, not the point on the ground that we actually want:-

To get around this, I simply discard any contacts coming from colliders outside the planes indicated by the dashed lines in the diagram above. So in this example the box's contact point would be discarded, and the ground contact point is used instead.

So all in all, this technique is a bit of a kludgy approximation of a true cylindrical collider, but it actually seems to work quite well. I'm pretty happy with the results!

Other stuff

I've also done load of code refactoring, bug fixes, UI improvements, rendering improvements (post processing effects, lighting), and other miscellaneous stuff over the past few months. Check it all out in the new demo build, have fun!

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: