2

All this started yesterday when I use that code for make a snippet:

void Start() {
    print("Starting " + Time.time);
    StartCoroutine(WaitAndPrint(2.0F));
    print("Before WaitAndPrint Finishes " + Time.time);
}
IEnumerator WaitAndPrint(float waitTime) {
    yield return new WaitForSeconds(waitTime);
    print("WaitAndPrint " + Time.time);
}

From: http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.StartCoroutine.html

The problem is that I want to set a static variable from a class of that type:

class example
{
    private static int _var;
    public static int Variable
    {
        get { return _var; }
        set { _var = value; }
    }

}

Which is the problem? The problem is that If put that variable in a parameter of a function this "temporal parameter" will be destroyed at the end of the function... So, I seached a little bit, and I remebered that:

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

From: http://msdn.microsoft.com/es-es/library/ms228503.aspx

But, (there's always a "but"), Iterators cannot have ref or out... so I decide to create my own wait function because Unity doesn't have Sleep function...

So there's my code:

    Debug.Log("Showing text with 1 second of delay.");

    float time = Time.time;

    while(true) {
        if(t < 1) {
            t += Time.deltaTime;
        } else {
            break;
        }
    }

    Debug.Log("Text showed with "+(Time.time-time).ToString()+" seconds of delay.");

What is the problem with that code? The problem is that It's very brute code, becuase It can produce memory leak, bugs and of course, the palayzation of the app...

So, what do you recomend me to do?

2
  • It seems very likely that you don't want to sleep. That is seldom the solution. What you do want is hard to tell. At least, I cannot understand the question. Commented Mar 11, 2014 at 14:20
  • The problem is that I want to know if there is a alternative, to Thread.Sleep (Game freezes), Tasks (FW4) or Yield return new WaitForSeconds (out and ref aren't compatible with Iterators that are used in this type of returns) Commented Mar 11, 2014 at 15:04

3 Answers 3

2

You could do something like this:

void Start()
{
    print( "Starting " + Time.time );
    StartCoroutine( WaitPrintAndSetValue( 2.0F, theNewValue => example.Variable = theNewValue ) );
    print( "Before WaitAndPrint Finishes " + Time.time );
}

/// <summary>Wait for the specified delay, then set some integer value to 42</summary>
IEnumerator WaitPrintAndSetValue( float waitTime, Action<int> setTheNewValue )
{
    yield return new WaitForSeconds( waitTime );
    print( "WaitAndPrint " + Time.time );
    int newValueToSet = 42;
    setTheNewValue( newValueToSet );
}

If after your delay you need to both read and update a value, you could e.g. pass Func<int> readTheOldValue, Action<int> setTheNewValue and invoke with the following lambdas () => example.Variable, theNewValue => example.Variable = theNewValue

Here's more generic example:

void Delay( float waitTime, Action act )
{
    StartCoroutine( DelayImpl( waitTime, act ) );
}

IEnumerator DelayImpl( float waitTime, Action act )
{
    yield return new WaitForSeconds( waitTime );
    act();
}

void Example()
{
    Delay( 2, () => {
        print( "After the 2 seconds delay" );
        // Update or get anything here, however you want.
    } );
}
Sign up to request clarification or add additional context in comments.

7 Comments

If by "FW2" you mean "Mono 2.6 inside Unity3D" the answer is they are compatible. I don't know where you can check but you can try it yourself: I was using Func<>, Action<> and lambdas in Unity3D in ~2011, it was already there and worked great.
Yes, sorry, I didn't check it... :P Action delegate: msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx
BTW, the exact .NET framework in Unity3D is not 2.0. The functionality is somewhere between 2.0 and 3.5, IMO closer to the 3.5 (you already have generics, lambdas and even some LINQ in Unity3D).
Well, I have a little problem, I want to set a color to a GUIStyle, the problem is that If I put Action<GUIStyle> all the properties/attributes will not be accepted by the compiler so how can I solve that?
Use my "more generic example", in the block of code containing "Update or get anything here" comment, set any value of any objects you like.
|
0

Is this what you want?

Thread.Sleep(time)

2 Comments

No, actually, it's not. Read the text of the printed messages. This wouldn't produce the desired output.
You should never block the GUI thread in Unity3D. Your game will freeze.
0

What you're looking for here can be accomplished using Task.Delay:

void Start()
{
    print("Starting " + Time.time);
    WaitAndPrint(2.0F);
    print("Before WaitAndPrint Finishes " + Time.time);
}
Task WaitAndPrint(float waitTime)
{
    Task.Delay(TimeSpan.FromSeconds(waitTime))
        .ContinueWith(t => print("WaitAndPrint " + Time.time));
}

You can then pass around lambdas/delegates, possibly closing over variables, to move data around your program.

2 Comments

I don't think there's a Task.Delay in Unity3D which is based on Mono 2.6 runtime.
Yes, well the problem is that Unity uses FW 2... And Task class is for FW4 (msdn.microsoft.com/es-es/library/…) So, is there another solution? :P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.