Making a RTS game #38: Using workers to construct buildings 3/3 (Unity/C#)

Today, let’s finish refactoring our RTS construction process!

This article is also available on Medium.

In the last two episodes, we worked on refactoring our building construction process so that, instead of placing them instantly on the ground, we have Worker character units build it gradually, over a short period of time.

So far, we’ve done the core logic and we’ve improved the visual a bit by having the building change shape throughout construction and even adding some VFX. Today, we’ll wrap this up by adding sounds and tweaking a few variables.

Replacing the basic ratio with a per-building construction time

So far, we’ve been working exclusively with 0-1 ratios. It was nice because it made it easy to evaluate whether a construction was finished, en route, what kind of mesh we should be showing, etc.

However, it is sort of limiting for a real game. In particular, it means that no matter how “big” a building is, the same group of workers will always build it in the same time. This is pretty unrealistic – we’d expect small buildings to be built faster, right? 😉

This means that instead of using the construction ratio directly, we should instead compute it from the current number of “build healthpoints”, compared to the “max healthpoints” of the building.

This can be done fairly easily in our Building class, by replacing our _constructionRatio with an integer _constructionHP and computing the ratio dynamically:

You see that I’ve also replaced my SetConstructionRatio() method with the SetConstructionHP() one.

Of course, this requires some updates in the other scripts!

For example, now, in the BuildingPlacer script, we need to pass in healthpoints instead of ratios in our SpawnBuilding() function:

And in the BuildingManager, we have to change two things. First, when we update the healthbar, we don’t have our ratio for the fill amount directly anymore; instead, we need to compute it from the current ConstructionHP and the building’s MaxHP. Second, the Build() function doesn’t need to convert the “build power” of the worker to a ratio-compatible value anymore: we can just keep it as is!

Finally, we have to change our debug console command to set HP and not a construction ratio, so it will now take in an integer parameter:

At that point, we’ve updated our codebase to support direct per-unit type build power, and we won’t have the issue of the “shared ratio” anymore 😉

For example, if you pick very different amount of healthpoints for the House and the Tower, and you set the Worker build power to be something like 10, you’ll see that when you ask the unit to build a House, it will take way longer than to build a Tower!

Of course, if you assign more workers to the construction, it will finish quicker, just like before 🙂

Fixing our building shortcuts

A few weeks ago, we added a basic system of shortcuts with a handmade input manager. For now, there aren’t a lot of shortcuts available, but there are two to place a new House or a new Tower.

The problem is that, at the moment, those shortcuts don’t use our new “worker-based” construction process! They simply create a building out of thin air without assigning anyone to its construction.

What would be better is to only enable this shortcut if there is at least one unit selected, and that this unit can build stuff (i.e. it’s buildPower is more than 0).

This is actually pretty quick to do: we just need to add some checks and early returns in the _OnBuildInput() callback function of the BuildingPlacer class:

Run the game again and you’ll see that:

  • if you try and press <H> or <T> (the “build a house”/”build a tower” hotkeys) without any unit selected, nothing will happen
  • similarly, if the selected unit(s) can’t build (i.e. they are buildings or their build power is 0), then nothing will happen either
  • but if at least one the selected units can build, it will be chosen for the construction and you’ll be able to place a new building on the ground

Playing a build noise!

The last thing I want to do in this episode is add some building sound during the construction.

Remember how we already have an ambient audio source on our buildings for when they’re ready? Well, what if we just used it earlier and first had a sound clip for the construction, then another one for the “alive” mode? 😉

Just like with the smoke effects we added last time, we’d like this sound to only play if there is at least one worker currently assigned to the construction.

I found another little audio clip on FreeSound.org, added it to my assets, and defined it as a new AudioClip variable inside my GameSoundParameters class:

Since we’ll need to access this clip from our Building class, let’s add a reference to our sound parameters Scriptable Object in the GameManager, alongside the others:

And now, all we need to do is use this audio clip when we first create the building, enable or disable it if we add/remove the last constructor from our list and replace it with the actual ambient sound when the construction is finished.

We need to be careful, though, to only enable and play sounds on our own buildings (i.e. the ones that have myPlayerId as owner) – otherwise we’ll be hearing all the contextual and ambient sounds from the enemy buildings as well!

If you restart the game, you’ll hear that the construction sound plays during the construction phase and is then replaced when the building is finished 😉

Conclusion

This episode was a bit shorter than usual, it was more of a way to tie up loose ends and finish refactoring our construction process… now, we have something more in the Warcraft 3/Starcraft 2 vibe that makes the building phase a bit more dynamic!

Next time, we’ll work on our game scene and some new features to our levels like spawn points, minimap icons and even minimap screenshots…

Leave a Reply

Your email address will not be published. Required fields are marked *