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 ronronmx · Mar 01, 2011 at 09:53 PM · coroutinereferenceienumeratoriterate

How to pass "ref parameter" in iterator method?

Hi all,
I need to pass a "ref" parameter to a IEnumerator method, but I sadly found out that it's not possible to use "ref" as a parameter in a iterator...here's my code below, which of course throws an error:

public class CountDownTimer : MonoBehaviour {

 public static IEnumerator CountDown (string objName, string displayEndText, float timer, ref bool boolToPass) {

     // Create a new GameObject for the countdown timer and child it to "HUD"
     GameObject countDownGO = new GameObject(objName);
     countDownGO.transform.parent = GameObject.Find("HUD").transform;

     // Create the GUIText component which displays the countdown and attach it to the countDownGO gameObject created above
     GUIText countText = countDownGO.AddComponent<GUIText>();
     countText.text = timer.ToString();
     countText.font = (Font)Resources.Load("Fonts/Arial Black", typeof(Font));
     countText.material = countText.font.material;
     countText.anchor = TextAnchor.MiddleCenter;
     countText.alignment = TextAlignment.Center;
     countText.transform.position = new Vector3 (0.5f,0.5f,0.0f);
     countText.lineSpacing = 1;
     countText.tabSize = 0;

     yield return new WaitForSeconds (1.0f); // Wait 1 second before starting the timer

     // While the timer is bigger then 1, decrease it every seconds and round the number to an int
     while (timer > 1) {

         timer -= Time.deltaTime;
         countText.text = Mathf.Round(timer).ToString();

         // When timer reaches 1, wait 0.5 seconds, then display end text and call callback function, wait 1 second then destroy the gameObject
         if (timer <= 1) {

             yield return new WaitForSeconds (0.5f);
             countText.text = displayEndText;
             boolToPass = true;

             yield return new WaitForSeconds (1.0f);
             Destroy(countDownGO);
             break;

         }

         yield return null;

     }

 } // End of CountDown IEnumerator function

I have looked around and found a few solutions, but I'm having a hard time understanding them and I haven't been able to successfully apply them to my own code. Could anyone show me how to do this with my code above?

Thanks a lot!
Stephane

Comment
Add comment · Show 1
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 Fattie · Jan 29, 2016 at 01:56 PM 0
Share

modern solution here ...

http://answers.unity3d.com/answers/551381/view.html

1 Reply

· Add your reply
  • Sort: 
avatar image
5

Answer by Bunny83 · Mar 01, 2011 at 10:25 PM

How about using a delegate? I don't know in for what special case you need this bool but with a delegate you can pass a callback routine.

public delegate void OnTimerExpired();

public static IEnumerator CountDown (string objName, string displayEndText, float timer, OnTimerExpired callback) {

[...]

 if (timer <= 1)
 {
     yield return new WaitForSeconds (0.5f);
     countText.text = displayEndText;
     if (callback != null)
         callback();

[...] }

void MyCallback() { // Timer expired }

// To start the coroutine use: StartCoroutine(CountDown("...", "...", 5, MyCallback));


edit

You can also pass an object to your coroutine. Classes are always reference types. Just create a class that holds the data you want to return.

public class CCoroutineResult
{
    public bool MyBool = false;
}

Define your coroutine like:

public static IEnumerator CountDown (string objName, string displayEndText, float timer, CCoroutineResult result)

You can easily change the bool inside your coroutine with: result.MyBool = true;


second edit
Well, just realised what you are doing inside your coroutine. You could go for another approach. StartCoroutine is a method of MonoBehaviour and the coroutine that is started is bound to the MonoBehaviour object. Since your function creates a temp GO you could run the coroutine on that gameobject. Just use a static method as a kind of constructor and remove the static from your coroutine. Create the GameObject within your static method and return the script instance.

public class CountDownTimer : MonoBehaviour
{
    public string displayEndText;
    public float timer;
    bool Done = false;
    private IEnumerator CountDown ()
    {
        // Here you can do all your stuff on the actual GameObject.
        // Just refer to `gameObject`
        [...]
    }
    public static CountDownTimer CreateTimer(float aDuration, string aEndText)
    {
        // Create a new GameObject for the countdown timer and child it to "HUD"
        GameObject countDownGO = new GameObject(objName);
        CountDownTimer CDScript = countDownGO.AddComponent< CountDownTimer >();
        CDScript.timer = aDuration;
        CDScript.displayEndText = aEndText;
        CDScript.StartCoroutine(CountDown());
        return CDScript;
    }
}
Comment
Add comment · Show 3 · 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 ronronmx · Mar 02, 2011 at 10:55 PM 0
Share

Bunny83, thx a lot for your great answer, it helped me understand a few things I was confused about! I'll give it a try and see if I can make it work with your example :)

avatar image ronronmx · Mar 02, 2011 at 11:12 PM 0
Share

I do like your solution on using a class as it's always a reference type, but the boolean I need to change is defined within another script, on another game object, so I would first have to create an instance of the other script in order to access the class, which I don't want to do.

I created the CountDownTimer.cs class so that I can access it from any other script, and change the variables of these other scripts by passing them to the CountDown() method. So if I pass a boolean variable to CountDown(myBoolen) and switch myBoolean to "true" withing CountDown(), I want it to update whichever boolean variable was passed to true as well.

I do have a version of this script which uses a delegate, and works like a charm, but I wanted to try a version which lets me change boolean states on other script without having to pass a callback method...I hope I make sense?

I haven't tried your second edit yet, but I will because I think it might fix my problem.

avatar image Fattie ronronmx · Jan 29, 2016 at 01:57 PM 0
Share

do not post comments as answers

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

1 Person is following this question.

avatar image

Related Questions

Can I use StartCoroutine inside of the same coroutine with a new variable? 0 Answers

Calling IEnumerator function with variables does not do anything 1 Answer

coroutine question c# 2 Answers

Lerp not working inside Coroutine. 1 Answer

Call a new IEnumerator 2 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