I have been designing a whitewater rafting game for a long time and had even developed a prototype for it some years ago.
The idea is basically endless rafting where you rush and feel the excitement of slopes and escape obstacles to do rafting further.
I didn’t use the prototype I have developed earlier and started developing the game from scratch. I will be telling details and development experiences as detailed as I can.
Before starting, I need to point that some of the work and all assets you see here are prototype and will be updated in the release.
Let’s start with the river system and flow direction implementation:
River system
River system is the core of River Rafters. Procedurally random placement of rivers needs some work. The meshes should be matching any combination, their textures should be seamlessly continue to be realistic and so on.
Furthermore; the boat player controls should be moving with the river. This is the most tricky part of the whole system.
Let’s first talk about the geometry of rivers.
River mesh and textures
Every mesh type starts from world origin directed towards the X axis and can finish in any direction. Meshes are randomly placed after one another, and player should not feel it that way. The most important things about river’s appearance are matching finishing and starting of every river mesh, and their textures being seamless in order not to break the continuity.
Mesh part is quite easy, their mesh just needs to be set that way in modeling software. Such as:
Texturing part is just a little bit harder than the mesh part. UV map of the river meshes are set as follows:
- Every river mesh length should be approximately same
- UV of every river should be the same length (I used UV for river start at X=0 and end at X=10)
- UV of every rectangle of a river mesh should follow the previous one in order to reflect the river flow. This was generated by Blender’s ‘Follow Active Quads’ option
River meshes are created with a curve and using array and curve modifiers in Blender:
Unreal Engine – Material
I separated the core material into mainly four parts: river flow, river foam, outlining and vertex displacement.
River Flow Material Function
River Foam Material Function
Simple outline
Vertex displacement(Work in progress)
Moving the player boat with river flow
Since the game is about rivers and their rushing speeds this part is the most tricky part of the game. I firstly tried some approaches like placing triggers at every turning point on every river but -as you can guess- it was awful. I couldn’t control the boat towards any direction and it felt silly. So I have come up with another solution:
I have implemented a static mesh to texture exporter that is capable of exporting river flow texture and determining map values like river texture world start and end positions and its world bounding box. It also exports a data table holding collectable and obstacle spawn positions but we will be discussing it in the following posts.
The texture exporter reads every vertex of the mesh and draws them by filling the flow direction as RGB using Barycentric Coordinate System just like a forward renderer do. The color of the texture are set using the following basic equation:
After exporting and assigning this texture to the relative river mesh data, they are mapped to every river type. Then the player movement component gets the flow data by telling its position to the river data holder, and moves along with this direction.
Result
Here, you can see the overall result of the system.
In this video boat follows the river perfectly for demonstration purposes. It follows the flow loosely in game.