Simple Stat Tracking

I want to give more information to the player (especially on death). Therefore, I think it's pretty clear that I want to start tracking what's going on in the game.

And, to an extent I already do that with a simple score system and random spawn system (with a limit of max enemies).

However, I'm worried about the complexity of said tracking. For instance, in a game where I'd like to have dozens of enemies should I just keep a static variable for each type of enemy and +=1 every time one dies? That would work, no doubt. But this seems inefficient and too crude.

This may be a better question for the forums but I feel like there's an answer just beneath the surface I'm not seeing. (Arrays?)

1 Answer

1

What you are looking for is an event system, which can be implemented either with C# delegates or the observer pattern. The observer pattern allows an object to notify others when a certain event happens. It's up to the other objects to handle the event.

Untested example code follows:

class Enemy : MonoBehaviour
{
   List<IObserveEnemyDead> observers_;
   public int enemyType_;

   public void OnDead()
   {
     foreach(EnemyObserver o in observers_) {
         o.NotifyEnemyDead(enemyType_);
     }
   }

   public void AddObserver(IObserveEnemyDead observer)
   {
      observers_.Add(observer);
   }

}

class TrackTypesOfEnemyKilled : IObserveEnemyDead
{

   Hashtable<int, int> killed_;

   public void NotifyEnemyDead(int enemyType)
   {
       killed_[enemyType]++;
   }
}

class TrackKillTypeXAchievement : IObserveEnemyDead
{
    int timesDone_;

    public void NotifyEnemyDead(int enemyType)
    {
        if (enemyType == Type.TypeX)
        {
           timesDone_++;
        }
    }  

}

So for example, you add the two observers to the Enemy. When the enemy is dead, it will inform the observers that it is dead, and the event also include what is the type. Note that the Enemy doesn't know concretely what is observing it. It just knows that it has to tell some objects the event.

You can also do the same thing faster with delegates without creating a new interface called IObserveEnemyDead. A delegate is more flexible, while the observer pattern specifies your intent clearer.

I haven't had time to test this, but this looks like what I need. Thanks!