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 /
  • Help Room /
avatar image
0
Question by RoelfMik · Oct 08, 2013 at 02:40 PM · variablereference

How to pass reference to variable in IEnumerator method in C#?

 using UnityEngine;
 using System.Collections;
 
 public class myTimer : MonoBehaviour {
     
     public int myInt1;
     public int myInt2;
     public int myInt3;
     
     void Start() 
     {
         
         StartCoroutine(ValueFader(0f, 100f, 5f, myInt1));
         StartCoroutine(ValueFader(0f, 180f, 5f, myInt2));
         StartCoroutine(ValueFader(0f, 115f, 5f, myInt3));
 
     }
     
     void Update()
     {
     
         //...
         
     }
     
     public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, out int myValue)
     {
     
         float myStartTime = Time.time;
         
         while (Time.time < myStartTime + myDuration)
         {
         
             myValue = (int)(myStartValue + ((myEndValue - myStartValue) * ((Time.time - myStartTime) / myDuration)));
             
             yield return null;
             
         }
         
         myValue = myEndValue;
         
     }
     
     void OnGUI()
     {
     
         GUI.Label(new Rect(0, 0, 80, 20), "myValue: " + myInt1);
         GUI.Label(new Rect(0, 20, 80, 20), "myValue: " + myInt2);
         GUI.Label(new Rect(0, 40, 80, 20), "myValue: " + myInt3);
         
     }
     
 }

Unity tells me: Error CS1623: Iterators cannot have ref or out parameters

What I want to do, is to be able to input/reference a specific variabel, whose value will be changed, from myStartValue to myEndValue, over time = myDuration.

Why doesn't it work? Can it be made to work? If not, how can I do this in a different way? I don't want to depend on Update(), preferably.

Thank you for your time! :]

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

2 Replies

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

Answer by ArkaneX · Oct 08, 2013 at 03:03 PM

Instead of passing ref/out parameters, you can pass Action:

 public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, System.Action<int> action)

and then call the action every time the value changes:

 action(myValue);

Of course in this case you have to declare myValue inside of method, because it is no longer a parameter.

You can call changed coroutine passing lambda expression as action. For example:

 StartCoroutine(ValueFader(0f, 100f, 5f, (x) => myInt1 = x));


Here's a convenient full example of that:

 private float stars; // it could even be a Property
 
 private IEnumerator _transition(string letterCode)
  {
  yield return StartCoroutine(
     Tween((x)=>stars=x, 3f,300f, 1f) );
  yield return new WaitForSeconds(1f);
  yield return StartCoroutine(
     Tween((x)=>stars=x, 300f,3f, 1f) );
  }
 
 private IEnumerator Tween( System.Action<float> var,
       float aa, float zz, float duration )
  {
  float sT = Time.time;
  float eT = sT + duration;
 
  while (Time.time < eT)
   {
   float t = (Time.time-sT)/duration;
   var( Mathf.SmoothStep(aa,zz, t) );
   yield return null;
   }
 
  var(zz);
  }

Hope it saves some typing.

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 Fattie · Jan 29, 2016 at 01:44 PM 0
Share

nice tip !

avatar image landon912 · Jan 29, 2016 at 03:44 PM 0
Share

You should also cache the lambda function in a member field in order to not feed the GC monster.

avatar image thexdd landon912 · May 03, 2016 at 11:50 AM 0
Share

Hi, landon91235! Could you provide an example of how to cache the lambda function in a member field, please? I would highly appreciate it.

avatar image
3

Answer by jschieck · Oct 08, 2013 at 03:11 PM

Well a different way of doing it would be to store the ints in an int[] then passing in the index, and setting that index in the coroutine like this

 using UnityEngine;
 using System.Collections;
 
 public class TestScript : MonoBehaviour
 {
     public int[] myInts;
 
     void Start()
     {
         myInts = new int[3];
         StartCoroutine(ValueFader(0f, 100f, 5f, 0));
         StartCoroutine(ValueFader(0f, 180f, 5f, 1));
         StartCoroutine(ValueFader(0f, 115f, 5f, 2));
     }
     void Update()
     {
         //...
     }
 
     public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, int myIndex)
     {
         float myStartTime = Time.time;
         while (Time.time < myStartTime + myDuration)
         {
             myInts[myIndex] = (int)(myStartValue + ((myEndValue - myStartValue) * ((Time.time - myStartTime) / myDuration)));
             yield return null;
         }
         myInts[myIndex] = (int)myEndValue;
     }
 
     void OnGUI()
     {
         GUI.Label(new Rect(0, 0, 80, 20), "myValue: " + myInts[0]);
         GUI.Label(new Rect(0, 20, 80, 20), "myValue: " + myInts[1]);
         GUI.Label(new Rect(0, 40, 80, 20), "myValue: " + myInts[2]);
     }
 
 }
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 Owen-Reynolds · Oct 08, 2013 at 09:34 PM 0
Share

To sum up, to pass a reference, pass a reference (in this ex, you could pass the array name and the index, for more flexibility.)

An array is a reference. A class variable is also a reference. In practice, your variables will often be in a class anyway, so you don't need to do anything extra.

In C++, you could pass a real reference, by just giving a pointer to an int. But C# won't allow that. The int must be bound up in some larger, memory-managed, object.

avatar image petey · Jul 03, 2017 at 03:58 AM 0
Share

Hey thanks for this!

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

Why is my referenced variable changing values? 1 Answer

Why is refrence to parent variable not updating 1 Answer

What are some best practices for static variables in multiplayer? 0 Answers

Access Main Camera and store it in a variable for quick access? 2 Answers

Component refrence goes null randomly? 3 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