Apologies for the lack of updates lately! I’ve been working on implementing pulleys and belts in the game, and I was hoping to get them finished before posting an update. However, as always seems to be the way, they’re taking longer than I expected. They’re not quite done yet, but I have made enough progress now that it’s worth talking about where things are at.
Pulley physics
The first thing I had to figure out was how to physically constrain a pair of pulleys together such that they would transfer motion and torque correctly. My plan was to use PhysX constraints (as exposed by Unity’s ConfigurableJoint) to accomplish this, in the exact same way I do for gears.
However, pulleys differ from gears in two important respects:-
- Pulleys transfer motion and torque over a distance, through the belt that connects them (unlike engaged gears, which must always be adjacent to one another).
- A pair of pulleys linked by a belt rotate in either the same direction or opposite directions, depending on whether the belt is in an open or cross configuration respectively (unlike a pair of engaged gears, which always rotate in opposite directions).
The first idea I tried was to set up a constraint whose anchor points were positioned on the edge of each of the pulleys, with motion locked along the tangent vector as shown below for two pulleys A and B:-
However, this didn’t work well at all because the constraint anchor points were separated by such a long distance. The pulley motion was unstable at anything other than very low RPMs.
So the next approach I tried was to instead calculate the two circles centered on each of the pulleys, whose radii are in the same proportion as the pulley’s, and whose edges touch each other. Then I placed the constraint anchors on the edge of these circles, represented by the dotted lines in the diagram below for the two pulleys A and B (again, motion is locked along the tangent vector):-
Note that these dotted circles are only used to position the constraint anchors, they aren’t visible and don’t interact with the world in any other way!
This method seems to work pretty well, it also easily allows for a cross configuration belt in a similar manner (by calculating proportioned circles whose edges instead touch in between the two pulleys, and positioning the anchor points where they touch).
Implementing pulleys in game
Actually getting the pulleys functional in the game required a lot more work beyond just the physics constraints. I wanted to allow the player to link an arbitrary number of pulleys together in whatever order they like, to form a chain that determines the route the belt takes through the pulleys.
For this I created infrastructure to associate or “link” parts together (or more specifically: link their part behaviours together). This needed to generalise beyond just pulleys, because I plan on also using it to link other parts together in the future (e.g. batteries, switches, motors, and eventually, more advanced control systems). It also needed to facilitate restrictions being applied (for example, in the case of pulleys, only allow linking if the pulleys are coplanar, and only allow each pulley to be linked to a maximum of two others).
Based on the order the pulleys are linked together, I also implemented a system to automatically calculate the belt routing (i.e. which side of each pulley the belt should go), which is then used to determine whether to use an open or cross configuration for the constraint between each pair of pulleys, as well as for positioning the visual representation of the belt.
I wanted pulleys to be able to move around slightly when the construction is unfrozen, but obviously there’s only so far a belt can plausibly stretch! So I wrote some code to deactivate the belt (both constraints and rendering) when any of the pulleys move too far from their original position, giving the appearance that the belt “broke”.
This work is complete now, and the pulleys are working in game. There are still a couple of major pieces left to do however:-
- Right now the links between the pulleys are hard coded just so I have something to test with. I still need to make a linker tool to allow the player to create and destroy the links themselves, as well as a UI to show these links.
- Currently I’m just using debug draw lines to visual represent the belt, so I need to implement some code to generate a proper render mesh for the belt.
But for now, here’s an example of some pulleys linked together, the yellow debug lines showing the links, and the black ones representing the belt:-
So lots left to do, but this should be really cool once it’s done, and I’m excited about the possibilities that the linker tool will allow for with other parts in the future!