BUILDING SYSTEM
Sep 24, 2024 - Solo School Project - Unity C#
Sep 24, 2024 - Solo School Project - Unity C#
Creative expression is the hallmark of a good game. That's why i decided to do a deep-dive on how building systems work. 🏡
<--
A building is comprised of building units
All building units are stored with their position as the key
New units are usually placed on pre-existing snaps
A "snap" is a position a unit can be in ( e.g a roof on walls )
Like units, all snaps are stored
Each frame, a ray is cast to check if there is something to snap on
What the raycast hits is dependent on the currently selected building unit ( e.g foundation, wall, roof )
Once a unit is placed, the snap it inhabits is disabled
The newly-made unit and snaps are stored
The inverse process is applied upon destruction
☆ The first part of this method sees if the current unit is taking up the space of any snaps.
Given value is false, it disables them. The second part checks the snaps attached to the unit. If the unit has snaps that are already occupied by other units, disable them. The opposite applies if value is true.
private void Place()
{
if (currentPlacement.placable == Placable.Unsnapped)
return;
GameObject unit = Instantiate(selection.prefab);
unit.transform.position = currentPlacement.position;
if (selection.rotationSensitive)
unit.transform.rotation = currentPlacement.rotation;
unit.name = selection.prefab.name;
DisableSnaps(unit.transform, true);
RegisterBuildingUnit(unit.transform);
}
☆ This gives some context to how these methods are used. currentPlacement is set based on a raycast interacting with both snaps and units.
☆ Here, a new building unit is registered into the two dictionaries ( snaps and units ). Notice the usage of RoundVector(). If I don't use this, then the position of certain snaps can't be used as keys because of floating point imperfection, due to the rotation of the snap's parent.
The system supports different types of building units ( walls, foundations, etc ). Each building unit basically has it's own Physics.Raycast profile so that it only CAN interact with the snaps it SHOULD be able to interact with. This greatly improves player experience as the player isn't having to aim around redundant and useless snaps.
I first followed some tutorials, and then iterated on them.
The expansion from the tutorials was my usage of C# dictionaries to map the positions of all the snaps and units to their GameObjects. This greatly saves on searching time ( making the game run smoother ).
After that, I focused on polishing the core mechanics of the system.
For example: a snap's collider has to perfectly match with the unit that will be built on it. This wasn't required in the long run because a snap gets disabled anyway when a unit is placed on it, but it makes the snaps feel better to interact.
The main beginning point of this project was finding a good tutorials series that suited my needs. Most building systems either are grid-based or top-down, but I wanted an "fps survival style" building system.