如何在 Unity 中等待特定的少量时间

问题描述 投票:0回答:4

我想为 for 循环的每次迭代等待 .01 秒,但我不知道为什么。

这是无需等待的纯代码。

public void BlackOut()
    {
        for (int i = 1; 1<255; i++)
        {
            Color tmp = gameObject.GetComponent<SpriteRenderer>().color;
            tmp.a = i;
            gameObject.GetComponent<SpriteRenderer>().color = tmp;

            //Wait here
        }   

    }

我想在评论处添加等待,但我尝试的一切都不起作用

在lua中是:

for i = 1,255 do
    --change color depending on engine
    wait(.01)
end

我试过等待几秒钟,task.delay,等..

c# unity3d
4个回答
3
投票

最简单的解决方案是将现有代码改编为协程。

  1. 通过将
    BlackOut
    更改为
    Coroutine
    使
    void
    成为
    IEnumerator
  2. 在您的//在这里等待评论
    使用
    yield return new WaitForSeconds(0.01f);
  3. 使用
    BlackOut
    “调用”
    StartCoroutine(BlackOut());
  4. 协程
public IEnumerator BlackOut()
{
    for (int i = 1; i<255; i++)
    {
        Color tmp = gameObject.GetComponent<SpriteRenderer>().color;
        tmp.a = i;
        gameObject.GetComponent<SpriteRenderer>().color = tmp;

        //Wait here
        yield return new WaitForSeconds(0.01f);
    }   
}

// How to run the coroutine
void SomeOtherMethod()
{
    StartCoroutine(BlackOut());
}

0
投票

正如 rshepp 回答的那样,在协程中执行此操作确实是个好主意,但我建议不要在循环中等待。

如果你这样写协程,你会把它绑定到 fps。在每个

yield return WaitForSeconds(...)
之间至少需要发生一帧。因此,在低帧率下使对象可见的速度将比在高帧率下慢。此外,在非常高的 f

而是使用适用于任何帧率(快或慢)的方法:

public IEnumerator BlackOut()
{
    const float fadeTimeSeconds = 2.5f;

    float startTime = Time.time;
    float currentTime = startTime;
    float stopTime = startTime + fadeTimeSeconds;

    var spriteRenderer = gameObject.GetComponent<SpriteRenderer>();

    while (currentTime <= stopTime)
    {
        currentTime = Time.time;

        var color = spriteRenderer.color;
        
        // currentTime-startTime is the time elapsed since the coroutine started
        // divide it by the fade time to get a value between 0 and 1
        // (we know it is between 0 and 1 because currentTime is between startTime and stopTime)
        color.a = (currentTime - startTime) / fadeTimeSeconds;
        spriteRenderer.color = color;

        // this makes the coroutine wait until next frame
        yield return null;
    }
    
    // make sure the fade is complete
    // without this code the fade could stop at for example 99% opacity
    var finalColor = spriteRenderer.color;
    finalColor.a = 1;
    spriteRenderer.color = finalColor;
}

0
投票

好吧,你可以采用异步,我现在使用它而不是协程。

async Task MyFunction()
{
    await BlackOut();
}


public async Task BlackOut()
    {
    for (int i = 1; 1 < 255; i++)
    {
        Color tmp = gameObject.GetComponent<SpriteRenderer>().color;
        tmp.a = i;
        gameObject.GetComponent<SpriteRenderer>().color = tmp;

        //Wait here
        await Task.Delay(10); // Paus 0.01 second
    }
}

如果您不熟悉异步,这里有一个非常好的比较异步和协程的教程: https://www.youtube.com/watch?v=WY-mk-ZGAq8


0
投票

这是一种没有协程的方法: 除了等待和更改值,您还可以像这样以与帧率无关的方式淡化颜色:

float timer = 0;
bool blacking_out = false;
SpriteRenderer spriteRenderer;

public void BlackOut()
{
    blacking_out = true;
}

void Start()
{
    spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
}

void Update()
{
    if(blacking_out)
    {
        timer += Time.deltaTime;
        timer = Mathf.Clamp01(timer);
        if(timer == 1f)
        {
            blacking_out = false;
        }
        // change color alpha over time. 
        Color tmp = spriteRenderer.color;
        tmp.a = timer * 255;
        spriteRenderer.color = tmp;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.