≡ Menu

Progress – A Free Achievement Framework for Unity

The Basics

Progress is a free (source included) achievement framework for the Unity engine. If you want something similar to Xbox 360 achievements or PS3 trophies in your game, then Progress is likely a decent start.

Download the full Unity project with source from GitHub here: https://github.com/spgar/Progress

The Inspiration

This week is the annual 7DRL (Seven Day Roguelike) Challenge. The basic challenge here is to develop a complete roguelike game in just seven days, which is no easy task. Roguelike games are notoriously complicated, and very difficult to balance and make fun – although you do get a free pass on graphics and brutal player deaths, so I guess it sort of balances out.

As a small child learning C++, I was a prolific developer of horrible, horrible roguelike games. I thought it might be fun to take on this challenge and see if I can do a little better with 8 or so years of professional game programming experience than I was able to as a ten year old trying to learn about pointers. Thinking a bit more, however, I realized that I don’t have nearly enough time in my schedule to devote to something like this over a week. I still wanted to make something though, so I took a few hours and made Progress.

If I had actually entered the 7DRL competition, my plan was to make a simple roguelike game based around achievements. There would be a whole bunch of achievements defined, and the win condition would require players to complete a whole wide variety of tasks/experiences and earn every achievement on one run through. Think breadth vs. the typical depth approach of roguelikes. I think this idea has some promise, and could be a lot of fun –  hopefully I’ll get back to it someday…

… or maybe someone other than me will make this kind of games, and I can try playing it? That would be cool too. If anyone wants to give it a shot, maybe this project will help you get started.

WebPlayer Example

Progress is a free achievement framework for Unity. Source code and all project files are included. Click on the image below for a webplayer preview, and read on to hear some of the details.

Walkthrough, Basic Information

The small sample app defined 9 different achievements and some simple controls that allow the player to gain the achievements. Here’s a quick rundown of the example achievements:

  • Dragon Slayer – Very simple, click the button that says “Kill the Red Dragon”. In a real game, killing the red dragon would likely be a much more visceral experience than just clicking this button – but the notification to the achievement system is the same.
  • Goblin Battle – Click the “Kill a Goblin” button. Kill 15 goblins.
  • The Invisible Man – There’s a toggle button that allows you to go into stealth mode. Spend 10 seconds sneaking around stealth mode and you’ll earn this achievement.
  • Junior Hero – There’s a display of your current level, and a button that allows you to level up. Get to level 5 and you’ll get this achievement.
  • Experienced Hero – See ‘Junior Hero’, reach level 10.
  • Potion Owner – There’s a very simple inventory/shop setup here that allows you to buy and drink three different color potions. Buy any potion to get this achievement.
  • Potion Hoarder – Own 20 different potions at the same time.
  • Potion Collector – Own at least one of each color potion at the same time.
  • Town Drunk – Drink 10 potions.

That’s the full sample list. I think this set represents a pretty complete view of the types of achievements that you see in games. If you want to add an achievement system into your game, this should be a pretty decent head start. Go ahead and play through the sample game in the webplayer, earn all of the achievements – it’s pretty easy. Check out the project, browse through the source, and you’ll see how this setup works. If you want a bit more information, then read on.

The included project only really has a couple of components:

  • Progress.scene – The sample scene.
  • AchievementManager.cs – Defines and displays achivements, tracks progress.
  • Hero.cs – Simulates a hero, passes info to the AchievementManager.
  • A couple of textures and a sound.
  • readme.txt

So basically there’s an AchievementManager where we define all of our achievements, and then a Hero that does heroic things and passes this info along in order to be rewarded with achievements.

So here’s what an achievement looks like that the player has not yet earned:

… and here’s what it changes to when you’ve earned the achievement:

Looking at this, we can see the basic information that goes into defining an achievement.

  • Name: The Achievement’s name. Currently used as an identifier, needs to be unique.
  • Description – Description of the achievement – often described how to earn the achievement.
  • IconIncomplete – The image to show before the achievement is earned.
  • IconComplete – The image to shotw after the achievement is earned.
  • RewardPoints – How many ‘points’ to give the player when he earns this achievement.
  • Secret – Is this achievement secret? If so, then we don’t show a description and we don’t show the RewardPoints until after the achievement is earned.
  • TargetProgress – Many achievements want to track progress of some sort, so this provides a target that we’re working towards. So if you’re trying to kill 15 goblins, then TargetProgress would be set to 15. More on this below.

So let’s go through how to author a sample achievement. I’m going to use the ‘Goblin Battle’ achievement as an example. So here’s how we setup the achievement in the AchievementManager:

Most of the information here should be pretty straightforward. We have a name, description, reward points, icon, etc. Let’s take a little closer look at the ‘Target Progress’ field, which is set to 15. Achievements in this system keep track of progress towards an achievement, which is represented as a float. When the current progress matches the set target progress – the achievement is unlocked. Some achievements only require a single action (such as Dragon Slayer), so the achievement is either ‘on’ or ‘off’ – but achievements like Goblin Battle keep track of an ongoing count.

How does this count get incremented? Here’s the code we use in Hero.cs to notify the AchievementManager that we’ve made some progress toward completing this achievement:

AchievementManager.AddProgressToAchievement("Goblin Battle", 1.0f);

Each time we call this function, the AchievementManager knows that we’re one step closer to the goal. When we kill that 15th Goblin, the achievement is awarded. Easy!

So what about achievements that don’t just move in one direction, but the progress can go back and forth? Take a look at the ‘Potion Hoarder’ achievement. This requires the player to own 20 potions at once, so the progress can increase or decrease. To inform the AchievementManager of the Hero’s progress, we use this function call:

AchievementManager.SetProgressToAchievement("Potion Hoarder", numRedPotions + numBluePotions + numGreenPotions);

Note that this call uses SetProgressToAchievement instead of AddProgressToAchievement. These are two different exposed methods to get the achievement behavior that you’re interested in. Use whichever one makes tracking your achievement easiest.

The progress values that we’re dealing with also do not have to be whole numbers. Take a look at ‘The Invisible Man’. This achievement tracks how long the player is in stealth mode, and is earned when the player hits 10 total seconds. Here’s the code we use to update that one:

if (inStealthMode)
    AchievementManager.AddProgressToAchievement("The Invisible Man", Time.deltaTime);

As you see here, we pass in the deltaTime whenever the player is in stealth mode. These are generally very small floats, and definitely not whole numbers.

The last thing I want to mention is that there’s some data on the AchievementManager that controls how the UI behind earning achievements works. There’s a sound (EarnedSound) that plays whenever you earn one, and two different GUIStyles (GUIStyleAchievementEarned, GUIStyleAchievementNotEarned) that control how text is displayed in the achievement display list. Before an achievement is earned, the text is a bit dimmed and once it is earned the text brightens up and becomes bold.

I think that’s about all you should need to know to work with Progress and add some sweet achievements into your Unity game.

Future Work

There are a bunch of different things that can be done to spruce up this project. Here are a few ideas off the top of my head that I had, but didn’t get around to.

  • Of course, add some sweeter icons and stuff. Make everything look better. Have the achievement list be an optional window that needs to be opened/closed.
  • Add something similar to the PS3 trophy colors: bronze, silver, gold, etc.
  • Convert over communication between the AchievementManager and the Hero to be more data-driven. Many of these achievements should be able to be authored without writing any actual code.
  • Maybe add alternate description text that gets used once the achievement has been earned?
  • Add potential visual effects for the moment when you earn an achievement in addition to the sound effect.

What Can I Use This For?

The code is officially under the MIT license. Feel free to use Progress for personal or commercial projects. All I ask is that you drop me a line and let me know what you used it for, as well as a mention in the credits/readme as per the MIT license.

Good luck, have fun!

{ 16 comments… add one }

  • coin-god March 6, 2011, 7:40 pm

    Awesome script. Thanks.

  • paulinho April 19, 2011, 10:16 pm

    To bad is not in javaScript:(

    I don´t use c#:(

    • Steve April 19, 2011, 11:55 pm

      Sorry man. If you want, feel free to convert the code over – it should be pretty straightforward.

  • Penny Chavez October 25, 2011, 9:12 pm

    hi i was doping in a line thank u for this sample i have been attempting to create a system like this, and had no idea where to begin and this is a great starting point example. thank u very much!…that is crazy that u have been doing this since u was 8 different life style brought together by games how incredible then that could it get…. i think i found a new site to b a fan off :)

    • Steve October 26, 2011, 11:53 am

      Glad it helped you out!

  • Nathan April 5, 2012, 11:53 pm

    Hey mate I am 13 is it okay if I use this for a competition:

    • Steve April 6, 2012, 12:00 am

      It’s fine with me, as long as it’s within the rules of the competition.

  • gecko April 13, 2012, 9:33 am

    thanks a lot for the code sample!!! it helped me clean up my own achievement system :)

    • Steve April 13, 2012, 12:00 pm

      Glad it helped!

  • llaraets December 10, 2012, 8:53 pm

    Thank you very much for the Sample Code Steve, now i going to read it and examie the code and hopefully turn it in to a Quest systerm :)

  • Hawke May 10, 2013, 6:20 pm

    This looks like it will save my lead programmer a few hours. Planning on using it for an indie game for some competitions and hopefully commercially.

    Thanks a bunch for it, I’ll be sure to credit you as per the MIT license.

    • Steve May 10, 2013, 6:24 pm

      Glad to hear it – shoot me a message when your games come out, I’d love to check them out!

  • Richie July 1, 2013, 5:13 am

    Wow! this is amazing!, I’m a hobbyist and self taught in programming, so my level is very basic, I was implementing something very simple to control progress and achievements, but found this, and it open my mind!.
    the scripts are great and they are very well ordered, I don’t work with C#, but I’m learning a lot from this.
    thanks a lot!, and cheers from Colombia!.

    • Steve July 1, 2013, 11:50 am

      Hi Richie – thanks for the kind words and good luck with your project!

  • Alireza June 30, 2014, 6:58 am

    Hi Steve.
    I glad to see kind programers like you :)
    it saved a lot of my time. but its seems need a good save system and its more important the achievements system itself.
    its my big issue these days.

  • Damian April 6, 2016, 8:30 pm

    Cool and useful article, but I have one problem with it. How can I get look of array like yours? I mean when I am creating array of objects, I can’t expand them and write their description, name etc. I can only drag and drop a gameobject with proper component. Did you write custom inspector?

Leave a Comment