agiro agiro - 1 year ago 66
C# Question

Start coroutines when the class is not a MonoBehaviour

EDIT: The answer that solves this problem is indeed in the answer of the post whose duplicate is this one. If you have the same problem as in the title, please refer to the other post.

I made a simple rig that moves stuff over time like this:

Transform from;
Transform to;
float overTime;
IUIAnimationEvent chain;
public delegate void UIchain();
public event UIchain NEXT_FUNCTION;
public MoveAction(Transform from, Transform to, float overTime, IUIAnimationEvent chain)
{
this.from = from;
this.to = to;
this.overTime = overTime;
this.chain = chain;
}
public void Move()
{
MonoBehaviour _lead = new MonoBehaviour();
if (moveRoutine != null)
{
_lead.StopCoroutine(moveRoutine);
}
moveRoutine = _Move(from, to, overTime);
_lead.StartCoroutine(moveRoutine);
}
IEnumerator _Move(Transform from, Transform to, float overTime)
{
Vector2 original = from.position;
float timer = 0.0f;
while (timer < overTime)
{
float step = Vector2.Distance(original, to.position) * (Time.deltaTime / overTime);
from.position = Vector2.MoveTowards(from.position, to.position, step);
timer += Time.deltaTime;
yield return null;
}
if(NEXT_FUNCTION != null)
{
NEXT_FUNCTION();
}
}


However, to make it work like I wish, I have to instantiate them, so they can't be a
MonoBehaviour
. Notice what I did with the
_lead
variable. I made it so I could start
coroutines
like any other. If my class is NOT a
MonoBehaviour
, how to start a
coroutine
from it?

Or if that isn't possible, how to instantiate classes that ARE
MonoBehaviour
? I noticed the _use
AddComponent
instead, but the classes are not components. They are used by another component and will not be put on a
GameObject
from the inspector.

Answer Source

Coroutines must be bound to a MonoBehaviour. Or in other words, you will need at least one MonoBehaviour to start a coroutine. And sadly, you cannot instantiate a MonoBehaviour:

var mono = new MonoBehaviour(); // will not work

There is a workaround that I can think of right now. You write your coroutine as usual and then you start it from another class that inherits from MonoBehaviour. That is, a function only needs to return IEnumerator in order to be started as Coroutine.

If another is started, the already started coroutine is stopped and a new one is called

If you want to do it inside a non-MonoBehaviour class I'm afraid it will not be possible.

Remember: You will need at least one MonoBehaviour to start a coroutine.

I will call what you want to achieve: a Coroutine Management feature and my understanding is that you want to include that feature inside your non-MonoBehaviour class. But thanks to my **Remember** quote above you cannot do it right now.

But including it in-side a .dll might be possible as a .dll can contain many classes. And you can use Access Modifiers to enforce your rules (the internal modifier is my favorite).

If I were you I would treat Coroutine Management as a separate problem and would build a .dll to handle them separately so that it would not mess up with my game-play business.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download