Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problems with iterators in abstract classes

Discussion in 'Scripting' started by kaamos, Jan 21, 2016.

  1. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    48
    I'm having some trouble implementing an iterator in one of my abstract classes.

    Returns 2 compile time errors:
    Error 1 Using the generic type 'System.Collections.Generic.IEnumerator<T>' requires 1 type arguments
    Error 2 The body of 'Generator.Foo()' cannot be an iterator block because 'IEnumerator' is not an iterator interface type

    Foo works fine in a regular class, it just seems to fail every time when it's in this abstract class.

    Any ideas?
     
  2. Fajlworks

    Fajlworks

    Joined:
    Sep 8, 2014
    Posts:
    344
    It could be that is implicitly set as a private method, try adding public or protected in front of it. And virtual as well:
    Code (CSharp):
    1. public virtual IEnumerator Foo()
    2. {
    3.      Bar();
    4.      //wait a frame
    5.      yield return null;
    6. }
     
  3. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    48
    Unfortunately I already tried that and it produces the exact same errors...
     
  4. Fajlworks

    Fajlworks

    Joined:
    Sep 8, 2014
    Posts:
    344
    So, I did a quick test:

    Code (CSharp):
    1. public abstract BaseAbility : MonoBehaviour
    2. {
    3.      public virtual IEnumerator TestEnumerator()
    4.      {
    5.           Debug.Log("Works");
    6.           yield return null;
    7.      }
    8. }
    9.  
    10. public DamageAbility : BaseAbility
    11. {
    12.      void Start()
    13.      {
    14.           StartCoroutine( base.TestEnumerator() );
    15.           // prints Works!
    16.      }
    17. }
    Mine compiled correctly and worked without problems. I would however investigate those Error1 and Error2 you're getting. I see you are using IEnumerator<T>. You can post your full code, maybe that way we can see what is wrong. Usually errors provide all the necessary information to solve them :)
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    The compiler thinks there should be a generic.

    You didn't include a generic:
    Code (csharp):
    1.  
    2. IEnumerator Foo()
    3.  
    Furthermore, Unity expects coroutines to use the NON-generic version of IEnumerator.

    I'm betting at the top you don't have:

    Code (csharp):
    1.  
    2. using System.Collections;
    3.  
    and you do have:

    Code (csharp):
    1.  
    2. using System.Collections.Generic;
    3.  
    Include the System.Collections; as well. Or explicitly spell out the full class name on Foo's return type:

    Code (csharp):
    1.  
    2. System.Collections.IEnumerator Foo()
    3. {
    4. ...
    5.  
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Impressive deduction of the error there, lord.
     
  7. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    48

    Impressive indeed! You nailed it. Thanks so much. So to summarize a solution should my past self somehow find a google wormhole and see this thread, or more likely someone else suffering the same error:

    Coroutines must use a nongeneric version of IEnumerator. So include System.collections as well.

    Again, thanks lordofduct, and everybody else who took a shot at helping out.
     
  8. JKarkkainen

    JKarkkainen

    Joined:
    Mar 5, 2013
    Posts:
    11
    I can't believe this is the first time I fell into this trap! Thankfully this was one of the first results on my google search and I managed to get here, and this totally fixed the issue. Only reason I haven't stumbled upon this before might be that usually Unity provides a using System.Collections; at the start, and usually I don't remove the defaults there, just add what I need.

    THIS time however, to clean the code up a bit, I used Visual Studio's remove unnecessary using's... and then I tried to add a coroutine. *facepalm*

    Thanks all for the solution!