Applying a temporal weakness on player

First of all, excuse the poor choice for the question title but I really have no idea what else I could call it.

I want to achieve the following scenario:

When the player collides with enemy X0, the player is slowed down for n seconds. If within those n seconds, a player collides with enemy X1 then the timer resets and the player is slowed down further for another n seconds. The above will be repeated until the player is able to avoid from being afflicted by any further enemies of type X.

Now what I have so far is that when my player collides with X; it is slowed down and furthermore if it collides again within those 3 seconds it will slow down further. I also have that if the player is not afflicted for n seconds then the player has normal speed again.

What I DON’T have is a correct time reset. The time is not being reset back to 0 whenever a player collides with more enemies within those n seconds.

Here is my code

public float slowDown = 0.2f;
	public float weaken = 1f;
	//public float counter = 0f; 
	public float afflictionTime = 3f;
	private static GameObject redCell;
	private Move MoveScript;
    
	// Use this for initialization
	void Start () {
		//set micro affliction (fyi it's very damaging)
		//counter = 0;
        
		if (GameObject.Find ("redCell") == true) {
			redCell = GameObject.Find ("redCell");
			MoveScript = redCell.GetComponent<Move> ();
		}
	}
    
	// Update is called once per frame
	void Update () {
		if (GameObject.Find ("redCell") == true) {
            //Debug.Log (MoveScript.getCurrentAfflictionTime());
			if (MoveScript.isAfflicted ()) {
				if (MoveScript.getCurrentAfflictionTime() < afflictionTime) {
                    //Debug.Log (counter);
                    Debug.Log (MoveScript.getCurrentAfflictionTime());
                    MoveScript.updateCurrentAfflictionTime();
					//counter += 1f * Time.deltaTime;
             //   } else if (MoveScript.getCurrentAfflictionTime() >= afflictionTime) {                
			//		resetCell ();
			//		Debug.Log ("heal!");
				}
			}
		}
	}
    
	void OnTriggerEnter (Collider c) {
		if (c.gameObject.tag == "Player") {
            //counter = 0;
            MoveScript.resetCurrentAfflictionTime();
			//afflictCell ();
			//slowCell ();
            StartCoroutine(affliction(afflictionTime));
		}
	}

    IEnumerator affliction(float afflictionTime){
        afflictCell();
        slowCell ();
        yield return new WaitForSeconds(afflictionTime);
        resetCell();
    }
    
	void afflictCell () {
		MoveScript.setAffliction (true);            
		MoveScript.incAfflictionCounter ();
	}
    
	void slowCell () {
		MoveScript.setMoveSpeed (slowDown / MoveScript.getAfflictionCounter ());        
	}

	void resetCell () {
		MoveScript.setAffliction (false);
		MoveScript.setMoveSpeed (1f);
		MoveScript.resetAfflictionCounter ();
	}

I have tried fiddling with the IEnumerator method to no avail, I just cannot seem to fix this. Any help would be greatly appreciated.

Thank you :slight_smile:

Hi,

I didn’t understand If I get even weaker on the second hit or if the level of weakness stays the same and only the timer gets reset.

I will show you both to be sure :slight_smile:

I will also ignore your variables names - would be too easy otherwise :smiley:

Option 1: Time gets reset, level of weakness stays the same

float lastHitTime = -9999f;
float weaknessDuration = 3f;
bool isWeak = false;

IEnumerator weaknessChecker(){
  while(true)
  {
    isWeak = lastHitTime+weaknessDuration > Time.time;
    yield return null; // see ya next frame
  }
}

void Start()
{
  StartCoroutine(weaknessChecker());
}

// if player gets hit, just do this:
lastHitTime = Time.time;

Option 2: Time gets reset, level of weakness increases on hits

float lastHitTime = -9999f;
float weaknessDuration = 3f;
int weaknessLevel = 0; // 0 means not weak

IEnumerator weaknessChecker(){
  while(true)
  {
    bool isWeak = lastHitTime+weaknessDuration > Time.time;
    if (!isWeak) weaknessLevel = 0;
    yield return null; // see ya next frame
  }
}

void Start()
{
  StartCoroutine(weaknessChecker());
}

// if player gets hit, just do this:
lastHitTime = Time.time;
weaknessLevel++;