Установка свойства шейдера (Propertyblock) дважды (затемнение цвета с помощью Lerp и восстановление его до исходного цвета) - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь сделать «мокрые следы», но у меня возникают некоторые проблемы с затуханием цвета и восстановлением его начального цвета при повторном использовании шага. У меня есть массив gameObject с несколькими шагами игрового объекта, и они располагаются на позиции ноги игрока, когда он касается земли. В настоящее время он объединяет эти шаги, и все работает нормально. Поскольку я хочу сделать его максимально легким, я использую шейдер для декали с блоком свойств, и мне нужно затушевывать свойство _MainColor, когда объект помещается, и когда этот же объект снова используется в другой позиции, его необходимо сбросить. , Проблема, однако, в том, что затухание не работает в его текущей настройке. В настоящее время происходит сброс цвета на черный при повторном использовании, и предполагается, что он снова исчезнет, ​​но вместо этого он снова мгновенно станет прозрачным.

void Update()
    {
        if (lastPos != transform.position)
        {
            stepPositioner = true;
            lastPos = transform.position;
            //Debug.Log("This Go changed position: ", this);
        }

        if (stepPositioner)
        {
            StartCoroutine(FadeTimer());
        }
    }

    IEnumerator FadeTimer()
    {
        _renderer.GetPropertyBlock(_propertyBlock);
        _propertyBlock.SetColor("_MainColor", startColor);
        _renderer.SetPropertyBlock(_propertyBlock);

        yield return new WaitForSeconds(1);

        _renderer.GetPropertyBlock(_propertyBlock);
        _propertyBlock.SetColor("_MainColor", Color.Lerp(startColor, endColor, Time.time * .5f));
        _renderer.SetPropertyBlock(_propertyBlock);
        stepPositioner = false;
    }

1 Ответ

2 голосов
/ 16 января 2020

Это не то, как Lerp работает.

Линейная интерполяция между цветами a и b по t.

t ограничен между 0 и 1. Когда т равен 0, возвращает а. Когда t равно 1, возвращается b.

Вы называете это только один раз с небольшим небольшим коэффициентом около 0,5 / 60, так что около 0.008333 получается почти начальное значение.

Кроме того, вы ждете одну секунду перед сбросом stepPositiontimet, поэтому на одну секунду метод Update запускает несколько сотен одновременных сопрограмм!

Для затухания цвета в течение одной секунды используйте что-то вроде

IEnumerator FadeTimer(float duration)
{
    // This has to be done right away!
    // Otherwise you get concurrent routines!
    stepPositioner = false;

    _renderer.GetPropertyBlock(_propertyBlock);
    _propertyBlock.SetColor("_MainColor", startColor);
    _renderer.SetPropertyBlock(_propertyBlock);

    var timePassed = 0f;
    while (timePassed < duration)
    {
        _renderer.GetPropertyBlock(_propertyBlock);
        _propertyBlock.SetColor("_MainColor", Color.Lerp(startColor, endColor, timePassed / duration));
        _renderer.SetPropertyBlock(_propertyBlock);

        // Add the time since last frame
        timePassed += Time.deltaTime;

        // Tells Unity to "pause" the routine, render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // Just to be sure set the final value in the end
    _renderer.GetPropertyBlock(_propertyBlock);
    _propertyBlock.SetColor("_MainColor", endColor, );
    _renderer.SetPropertyBlock(_propertyBlock);
}

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

StarCoroutine(FadeTimer(2)); 

, например, чтобы оно исчезло в течение 2 секунд


Примечание: напечатано на смартфоне, но я надеюсь, что идея проясняется

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...