Skip to content

An FPS game in the style of Minecraft. This is my first attempt at writing a voxel engine and multiplayer system in Unity.

License

Notifications You must be signed in to change notification settings

MrPio/Blockstorm

Repository files navigation

Blockstorm

An FPS game in the style of Minecraft. This is my first attempt at writing a voxel engine and multiplayer system in Unity.

🧊 What is a Voxel Engine?

For example, a cube map of size 128x128x10 has 163,840 cubes, which are 1,966,080 triangles and 5,898,240 faces. If each cube is a separate game object, Unity draws each one in a separate batch, i.e. a GPU operation. This is the fastest way to create a map, but it has a huge computational cost in the rendering phase, even for such a small map.

We could try enabling static batching on each cube to reduce the number of batches, but that doesn't change the fact that many unnecessary, hidden faces are drawn.

A Voxel Engine draws only the visible part of the map. The hidden faces, which are many, are not rendered. Also, the map is divided into chunks so that 1 batch operation can draw multiple blocks at once.

🎯 The Voxel Raycast problem

When digging or placing a block, we need to detect which voxel the player is looking at. A common approach to solving this problem is to draw a line of increasing length in front of the camera until it reaches a solid voxel or the reach length.

for (var lenght = 0.1f; lenght < Reach; lenght += 0.1f)
{
    var pos = Vector3Int.FloorToInt(_transform.position + _transform.forward * (length));
    var blockType = _wm.GetVoxel(pos);
    ...
}

Now, as the player may be looking at a block with a steep angle, we need to find a balance between how precise we want the Raycast to be, i.e. a small value for the step increment, and how fast we want it to be, i.e. how many steps are taken. In the example above, a value of 0.1 has been chosen.

However, as this whole operation is performed on each player's camera movement, it needs to be done as quickly as possible.

I, on the other hand, decided to use the higher-level `Physics.Raycast' Unity feature.

if (Physics.Raycast(ray, out hit, Reach, 1 << LayerMask.NameToLayer("Ground")))
    if (hit.collider != null)
    {
        var pos = Vector3Int.FloorToInt(hit.point + cameraTransform.forward * 0.05f);
        var blockType = _wm.GetVoxel(pos);
        ...
    }

This solution is not only faster, but also more general, as it can be applied to enemy damage detection. In fact, by changing the layer on which the ray is cast to "Enemy", we can detect whether the shot has reached the enemy and, if so, which part of his body has been hit, thanks to the multiple colliders.

🌍 Relay service

The relay service was used in conjunction with the lobby service to provide remote multiplayer. To avoid interfering with the host's router, firewall, and port forwarding, the relay system inserts a server between the host and the clients.

In this project, to switch between localhost and remote modes you should:

  • Deactivate the LobbyManager,
  • Activate the DebugManager,
  • Set the NetworkManager's transport protocol type to "Relay Unity Transport".

🧭 Roadmap

Task Done
Player movement βœ…
Basic Voxel Engine βœ…
UV mapping and texture atlas βœ…
Texturepack and BlockTypes array βœ…
Chunk subdivision βœ…
Map generator βœ…
Creating and deleting blocks βœ…
Submeshes for transparent blocks βœ…
Inventory management βœ…
Multiplayer implementation βœ…

πŸ–ΌοΈ In-Game Screenshots

vlcsnap-2024-09-08-14h37m25s975 vlcsnap-2024-09-08-14h37m23s070 vlcsnap-2024-09-08-14h44m27s061 vlcsnap-2024-09-08-14h37m08s955 vlcsnap-2024-09-08-14h36m59s045 vlcsnap-2024-09-08-14h36m45s626 vlcsnap-2024-09-08-14h36m28s344 vlcsnap-2024-09-08-14h36m09s382 vlcsnap-2024-09-08-14h35m24s158 vlcsnap-2024-09-08-14h35m07s167 vlcsnap-2024-09-08-14h34m59s535

πŸ–ΌοΈ Misc

Map.developing.demo.mp4

Screenshot 2024-07-15 101936

Screenshot 2024-07-15 102200

πŸ‘₯ Authors

Author Github profile
Valerio Morelli https://github.com/MrPio

About

An FPS game in the style of Minecraft. This is my first attempt at writing a voxel engine and multiplayer system in Unity.

Resources

License

Stars

Watchers

Forks

Packages

No packages published