Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by frarees · Feb 10, 2014 at 11:39 AM · coroutinepluginyieldc++

YieldInstructions from unmanaged land e.g. WaitForSeconds. Possible?

I see lots of third party tools depending on events and callbacks, but I'd like to know if it's possible to create coroutine-like behaviors (YieldInstructions, Coroutines) from C++.

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image lvictorino · Feb 10, 2014 at 11:43 AM 0
Share

You mean... like a thread?

avatar image frarees · Feb 10, 2014 at 11:55 AM 0
Share

$$anonymous$$g. WaitForSeconds, WaitForFixedUpdate, Coroutine. Those aren't implemented on managed side (AFAI$$anonymous$$).

avatar image whydoidoit · Feb 10, 2014 at 12:03 PM 2
Share

So if you have access to the main loop then you can do that - but I'm not sure how that would work as your probably don't. You could I guess write a C# wrapper and have it call into the C++ from the main loop as seen by the $$anonymous$$anaged code.

The principle of Unity Coroutines works based on the $$anonymous$$anaged ability to create state machines from functions that use the yield statement - so you would have to implement that kind of thing yourself, probably in a less "syntactically sweet" way (returning and expecting re-entrancy, probably be with a switch statement or some kind of function pointer manipulation).

avatar image whydoidoit · Feb 10, 2014 at 12:04 PM 0
Share

@lvictorino Coroutines are decidely not threads, they are more like old fashioned non-pre emptive multitasking.

avatar image frarees · Feb 10, 2014 at 12:13 PM 0
Share

Not likely to have access to the main loop. I was wondering if Unity held any interface, header to help doing so. Thanks

1 Reply

· Add your reply
  • Sort: 
avatar image
5

Answer by Bunny83 · Feb 10, 2014 at 12:28 PM

Your question is very vague what exactly you want to achieve.

Some words about Unity's coroutine mechanism:

  • Unity's coroutine scheduler is the only one who can start, run or continue a "Coroutine". This scheduler of course can't be modified.

  • The only possible yield values the scheduler understands are: - classes derived from YieldInstruction (WaitForSeconds, WaitForEndOfFrame, WaitForFixedUpdate, AssetBundleCreateRequest, AssetBundleRequest and Coroutine - a WWW object - "any other value" which isn't one of the above.

  • The YieldInstruction is just an empty class without any useful interface. The behaviour of the scheduler for the different YieldInstructions is hardcoded into the scheduler.

  • if "any other value" is yielded (which includes "null" a string value any other basic type such as int, bool, ... or a reference to an arbitrary object which isn't one of the above mentioned) the scheduler will "schedule" the coroutine for the next frame.

  • Coroutines are managed objects which are under the control of the Unity scheduler.

  • Coroutines implement a cooperative multitasking and are executed on the main thread like any other scriptcode in unity. There's no parallel execution at all.

Since most built in classes are sealed, you can't derive your own class from them. Also it wouldn't work out since the schedulers behaviour is limited to the known values. Your best bet is to write a seperate coroutine which polls each frame / x amount of time if it should continue or not. Something like this:

 //c#
 public class CoHelper : MonoBehaviour
 {
     private static CoHelper m_Instance;
     public static CoHelper Instance
     {
         get
         {
             if (m_Instance == null)
             {
                 m_Instance = (new GameObject("helper")).AddComponent<CoHelper>();
                 // DontDestroyOnLoad(m_Instance.gameObject);
             }
             return m_Instance;
         }
     }
     public static Coroutine WaitForSomeExternalCondition()
     {
         return Instance.StartCoroutine(_WaitForSomeExternalCondition)
     }
     private static IEnumerator _WaitForSomeExternalCondition()
     {
         bool done = false
         while(not done)
         {
             // check your condition and set done to true if your done
             
             yield null;
             // yield new WaitForSeconds(UPDATE_INTERVALL);
         }
     }
 }

With that helper you could do this in any coroutine:

 IEnumerator SomeRoutine()
 {
     Dosomething();
     yield CoHelper.WaitForSomeExternalCondition();
     DoSomethingOther();
 }

Keep in mind if you're using threads to use proper locking / synchronising.

edit
I forgot to mention that you could implement your own scheduler like this one: CoroutineScheduler. Unity's scheduler works in a very similar way, however the exact implementation we'll never see since it's implemented in the native part of the engines core. It might have some additional optimisations like a ordered queue for routines which yielded WaitForSeconds and so on.

Unfortunately the authors blog page about coroutines (which was great) doesn't exist anymore. However he kind of copied the content into this post. If you want to understand how coroutines and generator methods work, read it ;)

2. edit
Just re-read the question and i'm still confused what you want to do and where exactly. If this question was about if it's possible to implement coroutines in C++ the same way as in C# then the answer is clearly: no. That's because C# has the yield keyword which is a powerful compiler feature. A method containing a yield statement is translated into a class that implements IEnumerator and the method itself just returns an instance of that class. Since C++ doesn't have this feature you can't do it the same way. The C# compiler has to be very smart to translate your yield-code into a statemachine.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image frarees · Mar 19, 2014 at 02:15 PM 0
Share

Hey @Bunny83 haven't seen your answer before. Thanks for your reply, all the information here is quite useful.

I'll try to explain it. A lot of third-parties (e.g. iOS GameCenter plug-in), and usually ones that depend on network connection are exposed though APIs that depend on C# events or callbacks most of the time. I'd like to know if it's possible to create non-managed code in C/C++ and use it from C# with the Unity coroutine scheduler (e.g. yield return new WaitForGameCenterAuthentication (), where WaitForGameCenterAuthentication is external, implemented in native code). That would require access to some kind of Unity API at native level, I suppose. I've checked the Xcode project Unity generates to try to find native code concerning this.. but seen nothing interesting.. I hope you get the idea of what I'm trying to achieve.

What I'm doing right now is wrapping those third party librares as coroutines as you explain in your answer. It just works, but I'm curious about the possibility of doing this, just as WWW probably does.

avatar image Bunny83 · Mar 20, 2014 at 01:54 AM 0
Share

coroutines can't be "resumed" from an external event because, like is said, only the scheduler can resume a coroutine. The "things" you yield just get interpreted by the scheduler when it should resume the coroutine.

So if you yield a WaitForSeconds object the scheduler knows it should continue this coroutine after the specified amount of (game) time. Internally it has to check the state each frame and once the time has passed it resumes the coroutine.

There would be ways to implement resu$$anonymous$$g from "external events" but they have to be implemented inside the scheduler itself. This can't be changed unless you have a full source code license (which is very unlikely).

Alternatively you can implement your own scheduler and own coroutine mechanics if you like. However such an implementation doesn't use Unity's StartCoroutine / YieldInstruction objects, so the usage will be a bit different.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Import (mixed assembly) managed C++/CLI DLL plugin 0 Answers

WaitForSeconds problem with Unity Pro 3 Answers

Wait For Seconds to Load level C# 2 Answers

Corutine not behaving like it should? 1 Answer

Coroutine not running 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges