How to use StartCoroutine in inherited class?

public abstract class Abs{
}
public class A : Abs{
   public void Do(){
      StartCoroutine(Test());
   }
    IEnumerator Test(){
    }
}

This result error because A is not inheried MonoBehaviour.

But even after make class A be inside of another MonoBehaviour class, [non-static member…] error occurs.

How to solve?

Using coroutines need MonoBehaviour inheritance, that I’m sure of (people more experienced even stated that in other topics). But as I’m yet learning and didn’t have yet need, I’m not sure if you can inherit from more than one class like
public class A : Abs, MonoBehaviour { } or get it on parent, then it will be inherited in child too
public abstract class Abs : MonoBehaviour {} But here I’m not sure again since, I never yet used abstract classes. Though I found on quick google search on msdn example where abstract is inheriting so I guess that should work?
*Edit → Actually it seems like both should work. :slight_smile:

StartCoroutine is a member of MonoBehaviour. So you need to call it on a MonoBehaviour. But it doesn’t have to be from a MonoBehaviour. So this would work.

public abstract class Abs{
}
public class A : Abs{
   public MonoBehavior monoBehavior;
   public void Do(){
      monoBehaviour.StartCoroutine(Test());
   }
    IEnumerator Test(){
    }
}
1 Like

This does not compile…
Error says,
Assets/Scripts-my/MyScript.cs(34,13): error CS0103: The name `monoBehaviour’ does not exist in the current context

Hopefully this will help!

Output is:
-Started
-1
-2
-Finished

public class temp : MonoBehaviour
{
    public virtual IEnumerator Init()
    {
        Debug.Log("1");
        yield return new WaitForSeconds(1.0f);
        Debug.Log("2");
    }
}

public class bar : temp
{
    void Start()
    {
        StartCoroutine(Init());
    }

    public override IEnumerator Init ()
    {
        Debug.Log("Started");
      
        yield return StartCoroutine(base.Init());
      
        Debug.Log("Finished");
    }
}
1 Like

already said MonoBehaviour can’t be used because if I use it, I can’t manipulate variables in inspector.

and compiling after inherit MonoBahaviour deleted whole setting of that class variables…

my…

How did you implement it in your code?

If the class instance is a member of some MonoBehaviour, you should have a field to store a reference to the MonoBehaviour that ‘owns’ it, and then set that on Awake.

Use that reference to call StartCoroutine.

Example code:

public class MyScript : MonoBehaviour
{

   [SerializeField()]
   private ConcreateClass _obj;
  
   void Awake()
   {
     _obj.Init(this);
   }



   public class ConcreateClass : Abs
   {
  
     [System.NonSerialized()]
     private MonoBehaviour _owner;
    
     public Init(MonoBehaviour owner)
     {
       _owner = owner;
     }
    
     public void DoSomething()
     {
       _owner.StartCoroutine(this.DoSomethingRoutine());
     }
    
     private System.Collections.IEnumerator DoSomethingRoutine()
     {
       yield break;
     }
    
   }

}

If you’re getting errors you either didn’t copy the code right, or there is a minor syntax error because BoredMormon or I made a simple mistake as we wrote these in the browser here.

The error should be simple enough to resolve.

Do not rely on just COPY PASTE for code… you’ll never learn anything.

Such as this… WHY do you need a reference to a MonoBehaviour? How are we setting it? Why can’t this ‘ConcreteAbs’ and ‘Abs’ be a MonoBehaviour (not just that you notice you have inspector issues… there’s more to it than that)?

If you see such errors, you should know that there’s a typo.
@Kiwasi accidently declared it as ‘monoBehavior’ and wanted to use it and typed ‘monoBehavio__u__r’. Probably because he wrote it in the forums textbox.

But, if you copy&paste the code into your scripts, such errors should already be shown in your IDE, if not, you should really think about to switch to a proper one. But even without an intelligent editor, this one should have been easy to figure out. These are basics.

Init error, no return type, and if revise it as void, then error below.

NullReferenceException: Object reference not set to an instance of an object

and my codes are,

using UnityEngine;
using System.Collections;

public abstract class Abs
{
    public string name;
}
[System.Serializable]
public class A : Abs
{
    public int someInt;
}
public class AbsTest : MonoBehaviour {
    public A aval = new A();
}

and if make here Abs : MonoBehaviour to use StartCoroutine, AbsTest script’s Inspector’s aval variables disappears.

anyway, made it work.

using UnityEngine;
using System.Collections;

public abstract class Abs
{
    public string name;
}
[System.Serializable]
public class A : Abs
{
    public MonoBehaviour monoBehavior;
    public int someInt;
    public void Do()
    {
        monoBehavior.StartCoroutine(Test());
    }
    IEnumerator Test()
    {
        Debug.Log("Test called");
        yield return monoBehavior.StartCoroutine(Test2());
        Debug.Log("Test2 ended");
        yield return null;
    }

    IEnumerator Test2()
    {
        yield return new WaitForSeconds(1);
        Debug.Log("Test2 called");
    }
}
public class AbsTest : MonoBehaviour {
    public A aval = new A();

    void Start()
    {
        aval.Do();
    }
}

Seriously, did you read my post? :roll_eyes:
The one example provided by @Kiwasi only contains a typo.
Fix it and you might have what you want.

*Edit Okay, you were a lil faster but that’s just what has been suggested earlier lol

I would think you just pass Monobehaviour into your method in your class that doesn’t inherit from Monobehaviour:

public IEnumerator(Monobehaviour monobehaviour) {
    monoBehaviour.StartCoroutine();
}