Unity зависает при попытке изменить цвета RGB

Я пытаюсь постепенно изменять значения RGB Color32 компонента Unity Renderer с течением времени, но всякий раз, когда я играю в игру в Unity, программа просто зависает, и мне приходится закрыть ее. Я уверен, что это из-за того, как я пытаюсь его изменить, но я не знаю, где я ошибаюсь. Любая помощь будет принята с благодарностью. Спасибо.

void degradeGradually(Renderer ren){
    float time = Time.time; 
    Color32 col;
    while(((Color32)ren.material.color).r > 89f){
        if (Time.time - time > .025f) {
            time = Time.time;
            col = new Color32 ((byte)(((Color32)ren.material.color).r - 1f), (byte)(((Color32)ren.material.color).g - 1f), (byte)(((Color32)ren.material.color).b - 1f), 255);
            ren.material.color = col; 
        }
    }
}

person Ricardo Amaya    schedule 07.11.2018    source источник
comment
вы, вероятно, вызываете degradeGradually из обновления ... ваш вызов блокирует поток обновления ... Time.time никогда не изменяется ... просто замените while на if и сделайте float time = Time.time; полем   -  person Selvin    schedule 07.11.2018


Ответы (1)


Это связано с тем, что цикл while в этом методе никогда не завершается, и поэтому вызывающий его Update никогда не завершается. Это замораживает вашу игру.

Одним из возможных решений является превращение этого метода в сопрограмму (первый пример в документации удивительно похож на к вашему коду!) и поставить return yield null в конце цикла while:

IEnumerator degradeGradually(Renderer ren){
    float time = Time.time; 
    Color32 col;
    while(((Color32)ren.material.color).r > 89f){
        if (Time.time - time > .025f) {
            time = Time.time;
            col = new Color32 ((byte)(((Color32)ren.material.color).r - 1f), (byte)(((Color32)ren.material.color).g - 1f), (byte)(((Color32)ren.material.color).b - 1f), 255);
            ren.material.color = col; 
        }

        yield return null;
    }
}

И затем, где вы это называете,

 // Instead of degradeGradually(r);
 StartCoroutine(degradeGradually(r));

И если вам нужно что-то сделать сразу после того, как произойдет деградация, вы можете добавить это в конец degradeGradually.

            ...
            ren.material.color = col; 
        }

        yield return null;
    }

    DoStuffAfterDegrade();
}

Кроме того, значения цветовых компонентов находятся в диапазоне от 0f до 1f, поэтому вам нужно каждый раз уменьшать их на что-то меньшее, чем 1f. Как написано, вы станете черным на первом кадре, который вы получите внутри оператора if. Вам также, возможно, придется зажать ваши компоненты между 0f-1f, если Unity доставляет вам проблемы с вводом отрицательных чисел.

person Ruzihm    schedule 07.11.2018
comment
Это должно решить проблему с зависанием. С другой стороны, похоже, вы должны были спросить OP, что он/она пытается сделать, потому что это похоже на то, для чего следует использовать функции lerping, такие как функция Color.Lerp. - person PerformanceFreak; 07.11.2018
comment
Большое спасибо, оба ваших предложения сработали. объяснение IEnumerator позволило мне понять, как это работает, а использование Color.Lerp позволило мне сделать это намного проще, так что спасибо вам обоим. - person Ricardo Amaya; 09.11.2018