基于2个物体之间的距离的Lerp颜色

时间:2017-04-14 22:14:44

标签: c# unity3d

我想知道如何根据2个物体之间的距离制作平滑的颜色。颜色应从绿色到红色再到绿色到红色...... Cube far =颜色为红色,立方体附近=颜色为绿色。

我已经把所有东西都搞定了,但是唯一认为不起作用的是这个颜色没有平滑的事实。这就是目前的样子。 https://i.gyazo.com/a85852e76d2418ab7d44c18e152647c0.mp4

我正在使用此脚本进行颜色更改:

    FindClosestCube ();
    float lerpProgress = 0f;
    GameObject cubeChildTop = null;
    GameObject closestCube = FindClosestCube (); 
    cubeChildTop = closestCube.transform.Find("Top").gameObject;

    if (cubeDiffX >= 0.8f || cubeDiffX <= -0.8f) 
    {
        lerpProgress = 0.5f;
    }
    if (cubeDiffX <= 0.8f || cubeDiffX <= -0.8f) 
    {
        lerpProgress = 1f;
    }
    if (cubeDiffX >= 1.6f || cubeDiffX <= -1.6f) 
    {
        lerpProgress = 0f;
    }
    if(closestCube != GameObject.Find("Cube (1)2"))
    {
        cubeChildTop.GetComponent<Renderer>().material.color = Color.Lerp(redColor, greenColor, lerpProgress);
    }

那么......如何让它从红色变为绿色?

2 个答案:

答案 0 :(得分:3)

这很容易。

1 。找出您认为这两个物体可以分开的最大距离。

您需要做的第一件事是确定这两个游戏对象将与之分开的最大距离值。您需要将该值传递到#2 inValueMax函数的mapValue参数。

您可以使用以下代码确定最大值:

public GameObject obj1;
public GameObject obj2;

void Update()
{
    UnityEngine.Debug.Log(getSqrDistance(obj1.transform.position, obj2.transform.position));
}

public float getSqrDistance(Vector3 v1, Vector3 v2)
{
    return (v1 - v2).sqrMagnitude;
}

运行它,手动移动每个对象/多维数据集,然后获得最高值,两个对象可以通过Debug.Log消息相互传播。

看看您发布的视频我估计200的距离值是合适的,但如果您想获得完美的结果,仍然需要使用上面的脚本进行实验。

2 。使用map0MAX_DISTANCE距离范围转换为0f1f范围

float mapValue(float mainValue, float inValueMin, float inValueMax, float outValueMin, float outValueMax)
{
    return (mainValue - inValueMin) * (outValueMax - outValueMin) / (inValueMax - inValueMin) + outValueMin;
}

它将某个特定点之间的值进行缩放。

例如,您需要使用Lerp函数执行此操作,Lerp函数需要01个值。 mapValue函数可以将任意数字缩放到01函数所需的Lerp之间。

对我来说,我会将0200范围值缩放到0f1f范围,并使用mapValue函数。

3 。最后,使用Color.Lerp(near, far, lerp);来区分颜色。 lerp值是#2 的结果值。

代码

找到#1 后,将该值插入以下脚本中的MAX_DISTANCE变量即可:

public GameObject obj1;
public GameObject obj2;

Color near = Color.green;
Color far = Color.red;
const float MAX_DISTANCE = 200;

void Update()
{

    //Get distance between those two Objects
    float distanceApart = getSqrDistance(obj1.transform.position, obj2.transform.position);
    UnityEngine.Debug.Log(getSqrDistance(obj1.transform.position, obj2.transform.position));

    //Convert 0 and 200 distance range to 0f and 1f range
    float lerp = mapValue(distanceApart, 0, MAX_DISTANCE, 0f, 1f);

    //Lerp Color between near and far color
    Color lerpColor = Color.Lerp(near, far, lerp);
    obj1.GetComponent<Renderer>().material.color = lerpColor;
}

public float getSqrDistance(Vector3 v1, Vector3 v2)
{
    return (v1 - v2).sqrMagnitude;
}

float mapValue(float mainValue, float inValueMin, float inValueMax, float outValueMin, float outValueMax)
{
    return (mainValue - inValueMin) * (outValueMax - outValueMin) / (inValueMax - inValueMin) + outValueMin;
}

<强>结果

答案 1 :(得分:1)

似乎你对lerp的概念感到困惑。当您应用lerp时,lerpProgress应该是[0,1]中的连续值,以使其顺利更改。在你的caes中,你将它们设置为0,0.5,1.0,以及那些颜色不顺畅的地方。

请记住,lerp(线性插值)总结了两个值,每个值具有不同的贡献率。因此,如果您想要Color AColor B,那么您说我想要A的40%和B的60%并将它们混合起来。

每个实例应该拥有多少贡献率完全取决于您,而这正是您设计游戏的地方。

我能想到的一种方式是距离。如果ZXY之间移动,则XZYZ有两个距离比。如果ZX为40%(0.4f),对Z为60%(0.6f),则可以采用X颜色的40%例如,值{60} Y的颜色值。

这个想法不仅限于2个对象,还可以扩展到N个对象。

编辑:

以下是一个关于如何仅从X值中获得比率的示例。在这个例子中,我假设有两个预定义的minX和maxX值。

我们的想法是将leftX视为起点。如果x == left.x,则返回0,如果x == right.x,则返回1.

float GetDistanceRatio()
{
    float maxDistance = maxX - minX;
    float distanceFromLeft = currX - minX;
    float distanceFromLeftRatio = distanceFromLeft / maxDistance;

    return distanceFromLeftRatio;
}