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 MDarkwing · Jul 04, 2014 at 01:15 PM · c#coroutinesienumerator.net

IEnumerators saving passed value into two different variables.

I'm still fighting windmills trying to create ReplayCoroutine method for my CoroutineManager. My question is mostly based for IEnumerators:

If I pass and IEnumerator in a method

 CoroutineNode ReplayCoroutine(CoroutineNode cn)

and have a custom class

 public class CoroutineNode
 {
    public fiber;
    public fiberToCopy;
 
 
    public CoroutineNode(IEnumerator _fiber)
     {
         this.fiber = _fiber;
         this.fiberToCopy = _fiber;
     }
 
    public CoroutineNode(CoroutineNode cn)
    {
       fiber = cn.fiber;
       fiberToCopy = cn.fiberToCopy;
    }
 }

and now when I want to copy I pass not the fiber, but fiberToCopy which then this new CoroutineNode should have IEnumerators that are not iterated yet since its a copy of the original one. Is value of IEnumerator passed by ref or value?

I've read a bunch of stuff on msdn and as I get it most people tend not to fu** with IEnumerators in a way I am trying to do it. Any help is appreciated!

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Huacanacha · Jul 04, 2014 at 01:52 PM

An Interface is a Reference Type and is therefore passed by reference. In your code finer and fiberToCopy will refer to the same object.

You should pass an IEnumerable (a minimal enumerable interface to the underlying collection) then spawn a new IEnumerator whenever you need.

 public IEnumerable fiberSource;
 public IEnumerator fiberEnumerator;
 
 public CoroutineNode(IEnumerable fiberSource)
 {
     this.fiberSource = fiberSource;
     this.fiberEnumerator = fiberSource.GetEnumerator();
 }
 public CoroutineNode(CoroutineNode cn) : this(cn.fiberSource)
 {}
 

Edit: per Bunny's comments below you can indeed use IEnumerable (rather than IEnumerator) as the Coroutine return type so you can pass it to the CoroutineNode constructor. It's an interesting use-case... I'm glad this worked for you!

Comment
Add comment · Show 7 · 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 MDarkwing · Jul 04, 2014 at 11:25 PM 0
Share

That fairly makes sense but now I'm stuck with the thing that coroutine is IEnumerator and returns such type, how can i pass IEnumerator to constructor and get IEnumerable? Or much better can I implement coroutine so that it returns IEnumerable?

I apologize I'm not very good with generics and iterators

avatar image Bunny83 · Jul 05, 2014 at 12:20 AM 1
Share

Yes, you can simply change the return type of your coroutine to IEnumerable. That is actually the more used type in the .NET / C# world. An IEnumerator is one instance which is created whenever you call the generator function. An IEnumerable is an object which can generate multiple instances of that IEnumerator.

You just have to call GetEnumerator of your IEnumerable to get an IEnumerator. This one can be passed to StartCoroutine.

An IEnumerator can't be duplicated.

ps: I've never tried using IEnumerable as a coroutine, only for "normal" IEnumerables ;) But i think it should work.

avatar image Huacanacha · Jul 05, 2014 at 06:25 PM 1
Share

Interesting. I wasn't aware you could use IEnumerable type for a Coroutine method. If I can test this or find definitive information I'll add it to the answer.

Also btw, if you are purely using this for Coroutines don't worry about using Generics.

avatar image Bunny83 · Jul 06, 2014 at 07:34 AM 2
Share

Those "Coroutine methods" are actually a C# language feature and nothing added by Unity. They are called generator methods in general but also iterators (which microsoft prefers).

The real magic happens in the compiler as it turns your code inside that function into a state machine and wraps everything into an internal class. When you use IEnumerator as return type, the generator method returns an instance of that internal class. If you use IEnumerable as return type, the compiler creates two classes. The first is similar to the class you would get with IEnumerator, the second is a "wrapper" class which only works as closure for the parameters and provides (according to the IEnumerable interface) the GetEnumerator method which can create an instance of the interator with the original passed parameters.

That's also the reason why you can't use "ref" or "out" parameters for such methods since those can't be "stored" in the class.

There used to be a great blog post about how generators work internally by Fernando Zapata, the author of the CoroutineScheduler, but unfortunately his blog got "wiped out"

avatar image MDarkwing · Jul 07, 2014 at 02:06 PM 0
Share

Thank you guys for explaining this stuff to me. I know get it how this works and get the picture what should I do, and I've made this thing work. I'll tag Huacanacha solution as answer although all of you guys contributed to this.

Cheers! :)

Show more comments

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

22 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 avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Call Coroutine from value change event. 1 Answer

How do I pause a script while until after a function is done running? 3 Answers

How to ''stack'' coroutines, and call each one till all are executed? 5 Answers


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