Unity3D:尝试在C#中创建自定义睡眠/等待功能

时间:2014-03-11 14:14:18

标签: c# unity3d delay

所有这一切都始于昨天,当我使用该代码制作片段时:

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

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

问题是我想从该类的类中设置一个静态变量:

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

}

问题是什么?问题是如果把那个变量放在一个函数的参数中这个"时间参数"将在函数结束时销毁...所以,我进行了一些修改,然后我重新考虑了这一点:

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

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

但是,(那里总是"但是"),Iterators cannot have ref or out ...所以我决定创建自己的等待功能,因为Unity没有睡眠功能...

所以我的代码是:

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

该代码有什么问题?问题在于它是非常粗野的代码,因为它可能会产生内存泄漏,错误,当然还有应用程序的实现......

那么,你建议我做什么?

3 个答案:

答案 0 :(得分:2)

你可以这样做:

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

如果在延迟之后您需要同时读取和更新某个值,您可以例如传递Func<int> readTheOldValue, Action<int> setTheNewValue并使用以下lambdas () => example.Variable, theNewValue => example.Variable = theNewValue

调用

这是更通用的例子:

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

答案 1 :(得分:0)

这是你想要的吗?

Thread.Sleep(time)

答案 2 :(得分:0)

您在这里寻找的内容可以使用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));
}

然后你可以传递lambdas / delegates,可能关闭变量,来移动程序周围的数据。