【问题标题】:Setting a shader property (Propertyblock) twice (Fading out a color with Lerp and resetting it to the original color)设置着色器属性(Propertyblock)两次(使用 Lerp 淡出颜色并将其重置为原始颜色)
【发布时间】:2020-01-17 04:08:27
【问题描述】:

我正在尝试制作“湿脚印”,但在重复使用该步骤时遇到了一些淡出颜色并将其重置为起始颜色的问题。我有一个带有几个脚步游戏对象的游戏对象数组,当它接触地面时,它们被放置在玩家脚的位置上。它目前正在汇集这些步骤,一切正常。因为我想尽可能保持轻量级,所以我正在使用带有属性块的贴花着色器,并且我需要在放置对象时淡出 _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;
    }

【问题讨论】:

    标签: c# unity3d shader


    【解决方案1】:

    Lerp 不是这样工作的。

    在颜色 a 和 b 之间通过 t 线性插值。

    t 被限制在 0 和 1 之间。当 t 为 0 时,返回 a。当 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秒内消失


    注意:在智能手机上输入,但我希望思路清晰

    【讨论】:

    • 这确实像一个魅力,但我怎么能决定淡入淡出需要多长时间?不过,感谢您指出有关 lerping 的问题,我多年来一直在使用这个错误。
    • 只是将持续时间添加为参数,使其更清晰,更灵活。因此,只需将其称为StarCoroutine(FadeTimer(2));,例如在 2 秒内消失。
    • 你是个传奇!
    猜你喜欢
    • 2016-05-14
    • 2016-05-15
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多