I have created a delegate on a Script named BattleManager to handle the methods when the round is over.
Everything seems to work just fine except when there are multiple instances of the same object class adding to the delagate. Only the last method added to the deleagate works.
The Battle manager has the delegate like this:
public delegate IEnumerator OnRoundEnd();
public OnRoundEnd onRoundEnd;
I have a Effect class that adds to the onRoundEnd delegate. I have 3 objects with the class Effect and when they add to the delegate only the last one works. Other objects adding to the onRoundEnd work fine unless they are the same type. I have not found anything to get arround this issue
On the Effect class I add the method like this
public virtual void Init()
{
battleManager.onRoundEnd += OnRoundEnd;
}
Your
is basically nothing else than using
Func<IEnumerator>.You are expecting a return value - one single return value!
To understand a bit what happens here you have to understand what happens inside a
+=chaineddelegate(akaMulticastDelegate) - which internally is basically nothing more (ok it is a bit more) than a collection of the methods to call - once it is executed (the following samples are pure pseudo code and oversimplified - just for explaining the picture):First let's go back and take a
delegate voidSo far so good - all methods get executed in order, great!
Now a
delegate intYou can see now: The
resultwill get overwritten in each iteration => you end up only with the last value!Still though all the methods are executed.
Finally a
delegate IEnumeratorSo same as above!
resultis overwritten only with the last value.The additional "problem" about
IEnumeatoris now: It is "lazy" and nothing within it is executed until thisIEnumeatoris actually iterated usingMoveNext!Unity's Coroutine system does this for you internally and basically calls
MoveNexton a byStartCoroutineregistered/scheduledIEnumeratoronce a frame (except if using special timing YieldInstructions like e.g.WaitForEndOfFrameetc).So by the time you finally retrieve your
IEnumeratorand schedule it usingStartCoroutine(or manually callMoveNext) you are only aware of this very lastIEnumeratorinstance and will only get the behavior of that one.As mentioned I don't fully see how exactly you consume
onRoundEndbut as also mentioned you basically just have a collection of methods to call /IEnumerators to execute=> it might be easier to just stick to e.g. a
Queue- assuming each effect should only be executed once anyway:and then later on
and in your
Effect.Initinstead door use a
List<IEnumerator>instead