【问题标题】:Lerp color based on distance between 2 objectsLerp 颜色基于 2 个对象之间的距离
【发布时间】:2017-04-15 07:31:44
【问题描述】:

我想知道如何根据 2 个对象之间的距离制作平滑的颜色 lerp。颜色应该从绿色到红色再到绿色再到红色......远方 = 红色,近方 = 绿色。

我已经让一切正常了,但唯一认为不正常的是颜色不平滑。这就是它目前的样子。 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);
    }

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

【问题讨论】:

  • 很酷的游戏顺便说一句
  • @K Scandrett,非常感谢!每个级别都有自己的主题。

标签: c# unity3d


【解决方案1】:

这真的很容易。

1。找到您认为这两个对象可以分开的最大距离。

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

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

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 函数将 0 获取到 1 值。 mapValue 函数可以将任意数字缩放到01 之间Lerp 函数需要的范围内。

对我来说,我将使用mapValue 函数将0 范围值扩展到0f1f 范围。

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;
}

结果

【讨论】:

  • 感谢您付出这么多的努力!它完美地工作!顺便提一句。你用什么程序来制作 gif?
  • 不错。我使用 LICEcap 截屏。
【解决方案2】:

您似乎对 lerp 的概念感到困惑。应用lerp时,lerpProgress应该是[0, 1]中的连续值,以使其平滑变化。在您的 caes 中,您将它们设置为 0、0.5、1.0,这就是颜色显示不平滑的地方。

请记住,lerp(线性插值)是将两个值相加,每个值具有不同的贡献率。所以,如果你有 Color AColor B 想要 lerp,你是说我想要 A 的 40% 和 B 的 60% 并将它们混合起来。

每个实例应该有多少贡献率完全取决于您,这就是您设计游戏的目标。

我能想到的一种方法是距离。如果ZXY 之间移动,则有XZYZ 两个距离比。如果Z 是 40% (0.4f) 到 X 和 60% (0.6f) 到 Z,你可以取 X 的颜色值的 40% 和 Y 的颜色的 60%值,例如。

这个想法不仅限于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;
}

【讨论】:

  • 我能理解你的意思,但我不明白我将如何在我的脚本中做到这一点?顺便提一句。只有“x”在翻译。
  • 请检查已编辑答案中的代码 sn-p。这是一个如何计算 lerp 的典型示例。如果您正在寻找更具体的答案,请告诉我您希望如何实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多