How to increase score incrementally over time?

So, I have a system whereby NPCs will chase a player character. My goal is to setup scoring so that, while they are chasing, a score value will increase by 100 every 5 seconds, per NPC.

I've tried this code for scoring, attached to the NPCs and only called when they are in chase mode:

function Score(){

    if( !ProtectMode.protectMode ){
    	return;
    }

    else if( ProtectMode.protectMode ){
    	ProtectMode.scoreProtect += ProtectMode.scoreIncreaseRate * Time.deltaTime;
    }
}

...which references variables in the following script (ProtectMode.js), attached to a GUIText component of an empty GameObject for output:

@script RequireComponent(GUIText)

static var protectMode : boolean = true;

static var scoreProtect : float = 0;
static var scoreIncreaseRate : float = 500;

function Update () {
   guiText.text = "PROTECT:" + parseInt(scoreProtect);
}

The GUIText works fine, and the score increases when NPCs are chasing, but I expected this to add just 1 to the score every 5 seconds (because scoreIncreaseRate = 500). Instead, it looks like the score is increasing by at least 1 every frame. What's gone wrong?


EDIT: Sorry this isn't in a comment; I wanted to format this code.

This is what I came out with after trying while loop:

function Score(){

    if( !ProtectMode.protectMode ){
    	return;
    }

    else if (ProtectMode.protectMode){

    	while(true){

    	ProtectMode.scoreProtect += scoreAmount;
    	yield WaitForSeconds (5.0);

    	}
    }
}

The score still increases every frame, instead of as it should. Is this maybe because I'm calling Score() from within Update(), or because I've written it horribly?

If you want the score to increase in discrete steps of a fixed amount, each 5 seconds, you could implement something like this:

// put these with your var declarations
private var nextScoreTime : float;
private var scorePeriod = 5;
private var scoreAmount = 1;

// put this in your Update() loop:
if (Time.time > nextScoreTime && ProtectMode.protectMode)
{
    ProtectMode.scoreProtect += scoreAmount;
    nextScoreTime += scorePeriod;
}

Or, look up Coroutines as they are designed to do this sort of thing.

Right, if you want to do it using a Coroutine, your "Score" function needs to look like this:

function Score(){
    while(true) {
        if (ProtectMode.protectMode)
        {
            ProtectMode.scoreProtect += scoreAmount;
        }
        yield WaitForSeconds (5.0);
    }
}

There's no need for the part you had where it returns if protectMode is false. And you should only call this once, from your Start() function - not every frame in your Update() function. The reason for this is that once called, this function ticks over like a little engine automatically from then onwards, indefinitely monitoring the state of "protectMode" (until your game stops).

Also, notice that I've put the check for "protectMode" inside the while loop. This means that if "protectMode" ever gets changed back to false, the score will stop increasing, but the loop will continue to run - so it will work even if you change protectMode to false, and then later back to true.

using System.Collections;

IEnumerator socring ()
{
while (true)
{
ProtectMode.scoreProtect += scoreAmount;
yield return new WaitForSecond (5.0f);
}
}

void Start ()
{
StartCoroutine (scoring);
}

the code is untested and typed here but should work with correct spelling. you should attach this code to all of your NPCs it's a good idea to use static variables for score if you need to access the score from many objects