Вопрос

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?

Это было полезно?

Решение

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.
    } );
}

Другие советы

Is this what you want?

Thread.Sleep(time)

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top