Little trouble with IENumerator

Hey guys I’m having a little issue with using an IENumerator,
I’m currently trying to add an object to a list, apply an effect to the object
to the list for a certain duration then remove them from the list, the purpose of
the list to is disallow the object from having the effect applied to it while
the effect is already applied.

//abilityEffects contains a list of AbilityEffect objects
Public class ApplyAbilityEffects : MonoBehaviour 
{
	foreach (AbilityEffect abilityEffect in abilityEffects) 
		{
			StartCoroutine (abilityEffect.performBehaviour (other.gameObject));
		}
}


//EffectMovementModifier is a type of AbilityEffect
public class EffectMovementModifier : AbilityEffect 
{
	public override IEnumerator performBehaviour(GameObject inOther)
		{
			UnityEngine.Debug.Log ("test1");
			//MovementModification
			if (!objectsEffected.Contains(inOther.name))
			{
				inOther.GetComponent<BeastlingParent> ().getContainer ().getModifiers ().setMovementModifier (movementModifierAmount);
				objectsEffected.Add(inOther.name);
				UnityEngine.Debug.Log ("test2");
				yield return new WaitForSeconds (2);
			}
			else
			{
				//MovementDemodification
				inOther.GetComponent<BeastlingParent> ().getContainer ().getModifiers ().setMovementModifier (-movementModifierAmount);
				objectsEffected.Remove(inOther.name);
				UnityEngine.Debug.Log ("test3");
			}	

			yield return null;
		}
}

My issue is that ‘movement’ flickers on and off rather than waiting for 2 seconds.
when running, the debug.log tests all run simultaniously, rather than test 3 running once every 2 seconds.

Any insight into this would be greatly appreciated,
Bazzalisk.

You say test 3 should run every 2 seconds, but there is only a yield Waitforseconds() in test 2. It would seem your flickering is the rapid removal of any effects in the object continually in test 3. I don't entirely understand what you are checking with the other.name

1 Answer

1

it’s hard to tell exactly,
but at a glance i’d say if you want you should move the foreach loop inside the Coroutine.

the way it is now you’re iterating over everything in abilityEffects
and firing off simultaneous coroutines for each of them,
each of which waits two seconds at the end, but it doesn’t matter because they all started at the same time.

so instead of this:

void foo() {
    foreach (thing in things) {
        startCoroutine(doStuff(thing));
    }
}

IEnumerator doStuff(thing) { ... do stuff to the thing, then sleep 2 }

you probably want this:

void foo() {
    startCoroutine(doStuffToThings());
}

IEnumerator doStuffToThings() {
    for (thing in things) {
        ... do stuff to the thing ...
        yield return new WaitForSeconds (2);   
    }
}

yeah you should add code to make sure its called just once.