-
Notifications
You must be signed in to change notification settings - Fork 5
Development: Game Stats and Achievements
Game stats and achievements provide feedback to the player on how well they are doing and how much of the game they have completed. Game stats are always tracked on the client, when running via Steam they are also tracked by Steamworks. This document describes how to add a new stat and a new achievement.
If you don't want Steam integration than you just need a few classes from Rogue Wave to make his work. You can find them in Assets/_Dev/Runtime/Stats.
If you want to add Steam support then you will also need to install the open source FacePunch.Steamworks. Once installed set a Scripting Define Symbol of STEAMWORKS_ENABLED. If you want to create a build without SteamWorks enabled then replace this symbol with STEAMWORKS_DISABLED.

Once installed you will need to make a GameStatManager component available in your scenes. This component is set to persist across scenes so you only need to add it once:

That's it, you are now ready to start adding stats and achievements with, or without, SteamWorks integration.
In this section we will add a simple count of enemies killed.
- Right click in
Assets/_Dev/Resources/Game Stats - Select
Create -> Rogue Wave -> Stats -> Game Stat - Name the stat (in our case we will use "Generic Enemies Killed" as this will be the catch-all stat for enemy kills, we may add other stats for specific types of enemies later)
- Configure the stat in the inspector:

In order to update this stat we will need access to it in the BasicEnemyController, so we add it as a field:

We can then add our stat to this field as a default value. This will result in enemies using this stat, but we will be able to override it in individual enemies if we want to do per enemy counts.

Note that is you add this default after some enemies have been created it will not be set in those pre-existing enemies. You will need to add it manually.
Next we need to increment this counter when the enemy is killed. This is handled in the Die() method of the BasicEnemyController:

You can test in the editor fairly easily:
- Start the game
- Click the "Dump Stats and Achievements to Console" button in the
GameStatsManager - Kill at least one enemy
- Click the "Dump Stats and Achievements to Console" button in the
GameStatsManager - Verify that the count has increased one
If you test this now and have steam enabled the dump the dump will show you that steam is not yet updating. We'll cover that next.
That's it. Exactly where you will update the stat will vary with different stats, but the basic process is the same.
Enabling this stat in steam is super simple since our GameStatManager will automatically send stat changes to Steam if it is enabled. All you need to do is configure steam to recognize the stat key, visit Steamworks select your app, scroll down to Community Presence and select Achievements. Add your stat to the list:

Don't forget to publish the changes, then rerun the above test.
Now that we have a stat we can add an Achievement related to it. We'll add an achievement that unlocks when 20 generic enemies have been killed.
At this point it is worth noting that SteamWorks will handle achievements for you. If you do not intend to release outside of Steam then you could use their system which will remove a little local CPU. In this doc, however, we will assume that you want the option to release outside of Steam.
As with stats we store the details of our Achievement in a Scriptable Object. To create a new one follow these steps:
- Right click in
Assets/_RogueWave/Resources/Achievements - Select
Create -> Rogue Wave -> Stats -> Achievement - Name the Achievement (in our case we will use "Generic Enemies Killed (20)")
- Configure the achievement in the inspector:

That is it, you don't need to do anything else to enable the achievement in game, although if you are using Steamworks there is still a little work to do. You can test it in the same way you test the stats above.
You need to add an equivalent achievement to Steamworks. Be sure to use the same Key:

That's it, you are done. This Steam achievement should now unlock.
Let's look at another example, we will add a counter for the number of spawners destroyed. By doing this we will be making it super easy to create a similar Enemies Killed Count, since the code changes are the same for each. So we'll do that at the same time.
- Right click in
Assets/_Dev/Resources/Game Stats - Select
Create -> Rogue Wave -> Stats -> Game Stat - Name the stat (in our case we will use "Spawners Spawned")
- Configure the stat in the inspector:

Now repeat this process to create a Generic Enemies Spawned stat:

In order to update this stat we will need access to it in the BasicEnemyController, so, just as above, we add it as a field:

We can then add our Generic Enemy Spawned stat to this field as a default value, just as above:

In this case we want to count the number of spawners separately from the generic enemy spawns. So we change the setting for our spawner prefabs, while we are at it we will create a new stat for Spawners Destroyed and add that to the Spawner controller too.

Our Spawners Destroyed stat will already be working since we wired up the code for that above. However, we still need to wire up the code to increment the spawner spawned counter. This is a simple matter of Adding a few lines to the OnEnable method. Note that we don't add this in start since we are using pooled objects which are enabled/disabled as they are brought into the game and destroyed. We also need to ignore the first OnEnable as that will be when we instantiate it to go into the pool:

That's it, testing, Steamworks enablement and achievements are identical to the steps above.