如何在多种颜色之间进行Color.Lerp?


12

我发现很难在Unity文档中找到解决方案。

Color.Lerp(Color a, Color b, float t) 是一个函数,该函数根据步骤t逐渐更改颜色,从而为其提供颜色b的最终值。

如何在多种颜色之间一个一个地变色?

Answers:


13

_colors是一个颜色数组让LENGHT是阵列中的颜色的数量让是0..1浮点值

float scaledTime = t * (float) (LENGHT - 1);
Color oldColor = _colors[(int) scaledTime];
Color newColor = _colors[(int) (scaledTime + 1f)];
float newT = scaledTime - Mathf.Round(scaledTime); 

最终你可以使用Lerp

Color.Lerp(oldColor, newColor, newT)

+1-很好的答案-不需要任何循环或特殊分支,并且对N种颜色完全通用。
jpaver

当值1被命中时,颜色将是数组中的最后一个颜色吗?
G3tinmybelly 2015年

G3tinmybelly你是对的。t == 1的管理不正确。因此,我们可以在以下内容之前添加:如果(t == 1)返回Arr [N-1]
dnk drone.vs.drones 2015年

10

可以进行多种颜色转换的一种方法是利用Gradient

通过向开发人员公开此类型的公共变量,开发人员可以使用检查器启动“渐变编辑器”来设计包含任意数量的颜色的渐变。该编辑器允许您使用统一的颜色选择器,微调颜色/ alpha键的位置以及保存/加载渐变。

在此处输入图片说明

设计完成后,该Gradient.Evaluate()方法将接受0-1范围内的浮点数以返回适当的颜色。

using UnityEngine;

public class GradientTest : MonoBehaviour
{
    public Gradient myGradient;
    public float strobeDuration = 2f;

    public void Update() {
        float t = Mathf.PingPong(Time.time / strobeDuration, 1f);
        Camera.main.backgroundColor = myGradient.Evaluate(t);
    }
}

不幸的是,用于以编程方式构建渐变的API并不那么优雅


1
ColorBands可以用于相同的目标,但具有更大的颜色自由度
SteakOverflow

1
public float every;   //The public variable "every" refers to "Lerp the color every X"
float colorstep;
Color[] colors = new Color[4]; //Insert how many colors you want to lerp between here, hard coded to 4
int i;
Color lerpedColor = Color.red;  //This should optimally be the color you are going to begin with

void Start () {

    //In here, set the array colors you are going to use, optimally, repeat the first color in the end to keep transitions smooth

    colors [0] = Color.red;
    colors [1] = Color.yellow;    
    colors [2] = Color.cyan;
    colors [3] = Color.red;

}


// Update is called once per frame
void Update () {

    if (colorstep < every) { //As long as the step is less than "every"
        lerpedColor = Color.Lerp (colors[i], colors[i+1], colorstep);
        this.GetComponent<Camera> ().backgroundColor = lerpedColor;
        colorstep +=0.025f;  //The lower this is, the smoother the transition, set it yourself
    } else { //Once the step equals the time we want to wait for the color, increment to lerp to the next color

        colorstep = 0;

        if (i < (colors.Length - 2)){ //Keep incrementing until i + 1 equals the Lengh
        i++;
        }
        else { //and then reset to zero
            i=0;
        }
    }
}

因此,这是我最终用来在三种颜色之间进行编码的代码,希望对决定使用该代码的任何人有用。


0

我觉得可能有更好的解决方案。我会看到颜色之间发生变化的唯一原因是,如果您想不断更改色调... http://en.wikipedia.org/wiki/Hue

以下是将HSV转换为RGB的方法:http : //en.wikipedia.org/wiki/HSL_and_HSV#From_HSV

这样,您可以使用HSV颜色,只需更改色相,然后转换为RGB。此外,使用Color.Lerp,您还会遇到不一致的问题。如果从橙色变成黄色,然后变成绿色,您会发现颜色开始非常快地变为黄色,然后随着接近黄色而开始变慢,一旦经过黄色并变为绿色,则颜色再次加速。因此,它会减缓您要忍受的每个点的颜色变化。我认为更改色调会更加有效-长期而言,效果会更好。:)


0

您如何编写自己的利用版本的版本Color.Lerp()呢?

一个非常简单的版本,需要3种颜色,并将第二种颜色放在中间,看起来像这样:

Color Lerp3(Color a, Color b, Color c, float t)
{
    if (t < 0.5f) // 0.0 to 0.5 goes to a -> b
        return Color.Lerp(a, b, t / 0.5f);
    else // 0.5 to 1.0 goes to b -> c
        return Color.Lerp(b, c, (t - 0.5f) / 0.5f);
}

0

由于您没有说要更改颜色的内容,因此我将给出一个模糊的示例,其中包含在方法上创建的颜色。

关键是要具有颜色的集合,以及总的持续时间(如我将提供的示例所示)或每种颜色之间的持续时间(由您决定)。

我个人不对Update上的内容进行插值,因为我知道我不会一直插值(相机是一个例外),因此我使用协程来处理。

在此示例中,我将检查器上给出的持续时间除以颜色数量,然后将实际的迭代器颜色Lerp转换为下一个迭代器颜色,并且该持续时间将为先前拼接的持续时间。这是示例:

public class ColorLerping : MonoBehaviour
{
    public Color sampleColor; /// Just for debugging purposes.
    public float lerpDuration;
    public Color[] colors;

    void Awake()
    {
        StartCoroutine(LerpColors());
    }

    private IEnumerator LerpColors()
    {
        if(colors.Length > 0)
        {
            /// Split the time between the color quantities.
            float dividedDuration = lerpDuration / colors.Lenght;

            for(int i = 0; i < colors.Length - 1; i++)
            {
                float t = 0.0f;

                while(t < (1.0f + Mathf.Epsilon))
                {
                    sampleColor = Color.Lerp(colors[i], colors[i + 1], t);
                    t += Time.deltaTime / dividedDuration;
                    yield return null;
                }

                // Since it is posible that t does not reach 1.0, force it at the end.
                sampleColor = Color.Lerp(colors[i], colors[i + 1], 1.0f);
            }

        }
        else yield return null; /// Do nothing if there are no colors.
    }
}

希望能帮助到你。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.