InvokeRepeating function not stopping

Greetings, fellows.

Currently, I'm attempting to set up status effects, starting with the classic Poisoned. I want to make it so that, upon getting hit by a test projectile, the player gets poisoned (sPoison), losing a small percentage of their health every couple of seconds. And after a certain amount of time (PoisonTime), the Poison status goes away.

Poison code:

static var sPoison = false;
static var PoisonTime = 10.0;

function Update () {

    if (sPoison == true) {
        SendMessage ("timerPoison");
        InvokeRepeating("statusPoison", 1, 8);
    }
}

function statusPoison () {

    var PoisonDam = (PlayerHealth.playerHealth * .06);

    print ("Poisoned!");
    PlayerHealth.playerHealth -= PoisonDam;
}

function timerPoison () {
        yield WaitForSeconds (PoisonTime);
        print ("Poison cured!");
        sPoison = false;
}

Projectile code:

var InflictPoison = true;

function OnCollisionEnter(hit : Collision) {

    if (hit.gameObject.tag == "Player") {
        SendDamagePlayer ();
                Destroy(gameObject);
        }

function SendDamagePlayer () {

    var players : GameObject[] = GameObject.FindGameObjectsWithTag("Player");

    for (var go : GameObject in players)
    {
        var PlayeR = go.GetComponent(PlayerHealth);
        if (PlayeR == null)
            continue;

        if (InflictPoison == true)
            statuseffects.sPoison = true;

        PlayeR.BroadcastMessage("DamagePlayer", Damage);

    }
}

The problem I'm having, though, is that the status effect won't go away despite sPoison being false. And even worse, if this snippet doesn't have "sPoison = false;" in it, the player's health decreases exponentially.

if (sPoison == true) {
            SendMessage ("timerPoison");
            InvokeRepeating("statusPoison", 1, 8);
            sPoison = false;
        }

Any ideas on what the problem is?

You can't stop Invoke by changing the variable since Unity does not check your original function after you begin `InvokeRepeating`.

Instead use `CancelInvoke();` but be warned that stops all Invoked methods on this script.

Remove the Update function...Update runs every frame without exception; you don't need it for anything most of the time, and trying to use it for unrelated functionality just complicated things. Just call InvokeRepeating once when you need to and CancelInvoke when you want it to stop. As a simplified example, the projectile script would have this:

function OnCollisionEnter (hit : Collision) {
    hit.gameObject.SendMessage("Damage", 5.0);
}

and the player script would have this:

function Damage (time : float) {
    InvokeRepeating("Poison", 1.0, 1.0);
    yield WaitForSeconds(time);
    CancelInvoke("Poison");
}

private var health = 100;

function Poison () {
    health--;
}