3
\$\begingroup\$

This code is used in a MonoBehaviour script in my current code:

    // a simple WWW post
    WWW www = new WWW(this.Url, bytes);
    StartCoroutine(WaitForRequest(www));
}

// simple handler for the WWW error/return data.
private IEnumerator WaitForRequest(WWW www)

The problem is that I want to move this into a dll, that will be used by other dlls, not just monobehaviours, which as far as I can tell, means that StartCoroutine will no longer be available.

In .NET, Async and Await sounds similar, but I don't know how to use them. Is there a way to duplicate the Coroutine functionality? I do have access to UnityEngine.dll.

(If it is possible to use Coroutine without inheriting MonoBehaviour, that can work as well)

Thanks.

\$\endgroup\$
4
\$\begingroup\$

Yes, it is possible to do using iterators. I've put some pseudo C# code here to give you an idea. You use yield return to return something from an iterator, which has the same behavior as yield in a theoretical coroutine. You can then store the iterators in a list, dictionary, or other structure to keep track of them, and run them all. Note that coroutines are not a natively supported feature of C#, and are usually implemented using enumerators. I think Unity does it in the same way.

enum Status
{
   Running, Success, Failure
}

// An example of a coroutine that does something until some
// condition is true.
IEnumerable<Status> Coroutine(arguments)
{
    while(true)
    {
        DoStuff();

        yield return Running;

        if(Condition())
        {
            yield return Success;
            break;
        }
    }
}

// Keeps track of all running coroutines, and runs them till the end.
class CoroutineManager
{
     List<IEnumerator<Status> > Coroutines = new List<Enumerator<Status> >();

     // Starting a coroutine just means adding an enumerator to the list.
     // You might also want to be able to stop coroutines or delete them,
     // which might mean putting them into a dictionary
     public void StartCoroutine(Func<IEnumerable<Status> > func)
     {
         Coroutines.Add(func().GetEnumerator());
     }

     // Updating just means stepping through all the coroutines
     public void Update()
     {
         foreach(Enumerator<Status> routine in Coroutines)
         {
             routine.MoveNext();
         }
     }
}  

You then just need to call

CoroutineManager.StartCoroutine(YourFunction)

to begin the coroutine. Somewhere in your code you also need to call

CoroutineManager.Update();

each tick.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.