Can I use a custom component as a parameter of a IEnumerator?

I’m trying to make a poison/bleed mechanic by getting the GameObjectof the enemy hit then getting my hp helper custom Component of that GameObject then pass it to a helper class that would start a Coroutine to do the poison/bleed.

In that Coroutine, I passed the hp helper, dmg, and the duration to the Coroutine. I keep getting a NPE to something that I don’t know, it just point to the StartCoroutine and doesn’t point out which variable was causing the NPE so I decided to change way I call the IEnumerator. Before I was using something like StartCoroutine(Coroutine(hpHelper, dmg, duration)) then changed to StartCoroutine("Coroutine", params) where params is object[]. Using the latter just gave some stupid, pointing to a line that doesn’t make sense so I reverted to using StartCoroutine(Coroutine(hpHelper, dmg, duration)).

I swear that everything is not null. I’m still trying about what is the best way to make things work, I’m open to your suggestion on how can I implement this.

This is the error I’m getting if you’re interested.

NullReferenceException
UnityEngine.MonoBehaviour.StartCoroutine (System.Collections.IEnumerator routine) (at <f38c71c86aa64e299d4cea9fb7c715e1>:0)

Here’s the code where it all happens.

public void StartDebuff(Skill skill, GameObject target){
	EnemyController enemyController = target.GetComponent<EnemyController>();
	HealthHelper targetHpHelp = target.GetComponent<HealthHelper>();

	enemyController.debuffLst.Add(skill.debuffType);

	switch(skill.debuffType){
		case Skill.DebuffType.Poison:
			StartCoroutine( DamagePerSecondDebuff(targetHpHelp, skill.buffDebuffValue, skill.buffDebuffDuration) );
			break;
		case Skill.DebuffType.Bleed:
			StartCoroutine( DamagePerSecondDebuff(targetHpHelp, skill.buffDebuffValue, skill.buffDebuffDuration) );
			break;
		case Skill.DebuffType.Burn:
			StartCoroutine( DamagePerSecondDebuff(targetHpHelp, skill.buffDebuffValue, skill.buffDebuffDuration) );
			break;
	}
}

After some suggestion, I realized that I can’t use a MonoBehaviour class for what I want to do. So I did some changes to my code and made everything a Singleton. CoroutineHelper class that contains StartDebuff is now a singleton and my GameManager is also now a Singleton.

Now, I call StartDebuff like this

CoroutineHelper.Instance.StartDebuff(skill, colllidedToArr*.gameObject);*

Then call a real StartCoroutine() inside CoroutineHelper like this
GameManager.Instance.StartChildCoroutine( DamagePerSecondDebuff(targetHpHelp, skill.buffDebuffValue, skill.buffDebuffDuration) );
And that function looks like this
public void StartChildCoroutine(IEnumerator coroutineMethod){

  • try{*
  •  StartCoroutine(coroutineMethod);*
    
  • }catch(Exception e){*
  •  Debug.Log("StartChildCoroutine err: "+e);*
    
  • }*
    }
    And I still get a mysterious NPE.
    StartChildCoroutine err: System.NullReferenceException
    at (wrapper managed-to-native) UnityEngine.MonoBehaviour.IsObjectMonoBehaviour(UnityEngine.Object)
    at UnityEngine.MonoBehaviour.StartCoroutine (System.Collections.IEnumerator routine) [0x00014] in :0
    at GameManager.StartChildCoroutine (System.Collections.IEnumerator coroutineMethod) [0x00002] in PATH\GameManager.cs:40
    UnityEngine.Debug:Log(Object)
    GameManager:StartChildCoroutine(IEnumerator) (at Assets/Scripts/Utils/GameManager.cs:42)
    CoroutineHelper:StartDebuff(Skill, GameObject) (at Assets/Scripts/Utils/CoroutineHelper.cs:40)
    AOEController:Start() (at Assets/Scripts/Controllers/Skills/AOEController.cs:35)

Finally made it work. The cause was my incorrect implementation of the various Singletons I made

All I can think of is maybe one of the scripts (either the one that’s a parameter or the one running the coroutine) was destroyed, hence the null reference. I have no other ideas. A little tip, though: you can use multiple cases for a single block.

     switch(skill.debuffType){
         case Skill.DebuffType.Poison:
         case Skill.DebuffType.Bleed:
         case Skill.DebuffType.Burn:
             StartCoroutine( DamagePerSecondDebuff(targetHpHelp, skill.buffDebuffValue, skill.buffDebuffDuration) );
             break;

     // or you could just use an 'if'

Hi!
Unfortunately, you can only pass one parameter when dealing with coroutines.

Also, as a general tip, if possible, try to assign your Components instead of .GetComponent; it is more computationally expensive than most people think.