A game about a rabbit in a wall-bending boots, trying to escape from his lab that is just about to collapse!
I am a software engineer, trying to make games in Unity after work hours for fun. I had tons of fun making the the game I am about to present, but due to time constraints, it is far from being done: I created fully functional tutorial, with all the mechanics and elements that will be in the final game. Drawing art took me the most of the time as I have no prior graphics nor game development experience.
I hope you enjoy what I created, and also find useful some of the ideas I presented below.
Gumboot /ˈɡʌmbuːt/ is a long rubber boot - a wellington - but your boots are no ordinary gumboots. Your boots can deform the environment (making it behave like a gum or rubber) so that you can jump your way to the top of your rabbit hole/lab. It is about time as it is collapsing under your feet. Time to run!... Or jump.
Gumboots is a mobile game, in which the player plays a role of a rabbit scientist, wearing a high tech suit, with boots deforming the environment.
Here is a short gameplay demo:
Controls are easy to learn, but harder to master: press on the screen to start building up power; move the mouse to aim, and release to jump. Pressing quickly lets you build combos and move faster around the level.
Girders are guarding the structural integrity of the entire lab, so they are extremely tough and they cannot be bounced off.
Glass panels are one directional platforms. They can be jumped on from below, but they will not let you fall through.
Terminals are all over the laboratory, and can be used to open doors to which they are connected. Our rabbit is a skilled programmer, and he can type quick, so using the terminal is as easy as jumping next to it.
Carrots are snacks not only a good for your brain, but also for your muscles. They give you temporary jump boost to traverse the lab faster.
While most of the tools and techniques I used are quite standard, I would like to share two things I built custom for this game:
Deformable Sprite Shape -- the foundation of the levels and gameplay; this is what makes the walls and floors bouncy
Physics based motion for rabbit's ears -- ears are controller via IK targets, but targets themselves are controller via spring simulation, which yields a more realistic motion
Deformable Sprite Shape
New SpriteShape package is great when it comes to easy world editing: all level elements are done with sprite shape (platforms, doors, terminal-door connections).
However I wanted to make it more dynamic, as the core mechanic is to bounce from the environment and deform the elements. To achieve the wobbly effect you see above, I created DeformableSpriteShape -- a component that manipulates the attached SpriteShape -- whose nodes can be moved, and will return to their original position.
There are two core elements of this component:
subdividing the path (at the start) to increase the resolution of the deformation -- this is very easy thanks to the Sprite and Bezier utility classes shipped with the package.
simulating points as springs oscillating around their original points using Hooke's Law
Here you can see it in action:
There are several configuration options:
subdivision frequency and effect radius configure how dense paths will be and how close nodes can be to be displaced
spring constant defines stiffness of the spring (lower values, means slower motion)
dampening factor accounts for overshooting and slowing down movement over time
mouse force factor is how much displacement caused by mouse input are affecting the shape
Here is how one can achieve different effects by changing the spring constant:
Simulation itself is fairly simple: in FixedUpdate all points of the subdivided curve are updated with Euler's integration (which in my case happens to be quite stable):
// We keep a copy of the original spline so that we can calculate displacement correctly.
Displacement = CurrentPosition - OriginalSplinePosition;
// This formula comes directly from Hooke's Law.
Force = -SpringConstant * displacement - DampeningFactor * CurrentVelocity;
// JumpDisplacementForce is non zero if at this frame player jumped.
Force += JumpDisplacementForce;
// Euler's integration
NewVelocity = CurrentVelocity += Force * dt;
NewPosition = CurrentPosition + NewVelocity * dt;
In order to displace appropriate Deformable Sprite Shape, it has to be found in the level first, and it is a fairly straightforward process:
level controller keeps track of all present shapes
while requesting a shape and its node that is the closest to the player it goes through all of them, discarding those whose bounds are not close to the player (broad phase)
those whose bounds are close enough, are checked for the closest point
then a force is applied to the closest point that is causing the displacement
Note that there are some limitations of this component:
colliders are completely static - updating colliders at runtime is possible (and this option is currently available), but even doing so 10 times a second causes considerable performance drops
only curve's nodes can be deformed - at the beginning I experimented with dynamically adding deformation point on the curve closest to the deformation spot; however this become quickly really complicated in the code due to lack of API support -- entire API is index based, and there is no way to attach any custom data to the point, so keeping custom data outside of the Spline, while adding points would require updating indices, and would make the code quite complicated for something that could be supported natively in the API; to alleviate this shapes are subdivided and one can specify an "effect radius" in which corners are searched/snapped to the deformation place
deformed shape does not always look good - when nodes are too far from the original positions, generated mesh is sometimes too stretched (see above), so one has to play with the constants to achieve good looking effect; after many iterations I managed to create sprites that look good in most of the configurations, and pick constants that do not stretch sprites too much
Physics based animations
Rabbit is animated using new 2D Animation package with 6 IK solvers attached in total:
two for legs
two for arms
and two for ears.
While preparing, I watched a video describing 12 Disney's principles of animation, and I immediately knew that I would like to recreate at least one of them in my game.
Most of the body was animated using curves and standard animation tools, however ears are done differently in order to look more realistic. Targets for two IK ear solvers are free objects in the world-space, following dummy (invisible) targets parented to the rabbits body, in a physics based fashion to achieve "follow through" principle.
For the initial prototype I used built-in Spring Joint 2D, but the effect was far from being realistic, but amusing nonetheless.
Here again I used the same spring simulation as for DeformableSpriteShape, which gave me the control I needed, to make the effect feel right.