Add score when enemy is killed?

I have a gun script, that causes damage to the enemies. When their health is 0, the enemy is destroyed and a “dead” enemy (a ragdoll) is spawned in its place. The enemies are prefabs (so are the ragdolls), and are spawned in randomly. Its supposed to add 1 to a var in “ScoreKeeper.js” (on another object in the scene), and is connected to a thing that makes the score show on a GUI Text.

How can I make it so it adds 1 the the var “score” in “ScoreKeeper.js”?

Either right before the enemy is destroyed and replaced, or as soon as the ragdoll is spawned

Enemy Script:

var health = 100;
var AmountOfDamage = 10;
var theLevel : String;
var ragdoll : GameObject;
var enemyprefab : GameObject;
var relativePositionOffset : Vector3 = Vector3(0,0,0);
var Script : ScoreKeeper;
var CreateOneTime = true;
 

 function OnTriggerStay (myTrigger : Collider) {

 		if(myTrigger.gameObject.tag == "Bullet"){
  health = health - AmountOfDamage;
  }

  		if(health <= 0) {
  if(CreateOneTime)
  {
  Instantiate(ragdoll, transform.position + relativePositionOffset, Quaternion.identity);
  Destroy(gameObject);
  CreateOneTime = false;
  		
  		}

}
}

I know of three solutions: static variables, singletons, or ScriptableObjects.


A static variable is a variable that is shared by all instances of a class. If a static variable is public, then it can easily be referenced by anything as ClassName.staticVar. So in ScoreKeeper.js you’d just need to make your “score” variable static and public:

public static var score : int = 0;

It’s quick and easy and works well. The usefulness of static variables can also be a downside, however, if you ever need multiple ScoreKeeper.js instances with their own “score” variables.

Unity has a tutorial on static variables.


A singleton is common design pattern that makes it easy to find an instance of your class, for classes that should only have one instance at any time. In a lot of ways it’s similar to the static variable, except you’re getting static instance of the class, which has it’s own variable. A simple implementation might be:

public class ScoreKeeper {

    public static var instance : ScoreKeeper;

    var score : int = 0;

    function ScoreKeeper() {
        if (instance == null) {
            instance = this;
        } else {
            Debug.LogError("There should only be one instance of this!");
        }
    }
}

And then you could easily access the score variable using

ScoreKeeper.instance.score

Singletons are great for all sorts of stuff, and if it works for you then you should go for it. Similar to static variables, it’s possible to shoot yourself in the foot with singletons though. I encourage you to read more about singletons.


Last, but in my opinion the best and the most in Unity-style: ScriptableObjects. These are a class very similar to MonoBehavior (the same internally, I believe) except instead of attaching instances to GameObjects, the instances live as files in your assets folder. Components on your prefabs can all reference one of these ScriptableObject just by dragging and dropping in the inspector. Your ScoreKeeper would also reference the asset and update your UI when the score value changes (check out events if you don’t want to evaluate the score every frame!).

@CreateAssetMenu()
public class Score extends ScriptableObject {
    
    public var total : int;
}

ScriptableObjects are great because you can do all sorts of cool stuff with them once you get used to them. They are perfect for holding data you want to easily reference.

Unity has a nice tutorial on ScriptableObjects.

And here’s the video that sold me on ScriptableObjects.

You’ll need a reference to the score keeper object and add one to the score when you kill the enemy. You can do this with FindObjectOfType<ScoreKeeper>().score += 1 or something similar.