Unity在多个游戏对象上更改材质颜色

时间:2019-03-09 22:31:09

标签: c# unity3d

我做了一个右键单击菜单,当我将鼠标放在该菜单中的按钮上时,我想让对象改变材质的颜色。

这是代码:

Color[] startCo;

public void OnPointerEnter(PointerEventData eventData)
{
    GameObject[] objects = GameObject.FindGameObjectsWithTag(myMenu.selected.title);

    for (int i = 0; i < startCo.Length; i++)
    {
        startCo[i] = objects[i].gameObject.GetComponent<MeshRenderer>().material.color;
    }

    foreach (GameObject obj in objects)
    {
        obj.gameObject.GetComponent<MeshRenderer>().material.color = Color.red;
    }
}

public void OnPointerExit(PointerEventData eventData)
{
    GameObject[] objects = GameObject.FindGameObjectsWithTag(myMenu.selected.title);

    for (int i = 0; i < objects.Length; i++)
    {
        objects[i].gameObject.GetComponent<MeshRenderer>().material.color = startCo[i];
    }
}

使用first for循环根本不起作用,但是如果没有它,当我将鼠标置于按钮上时,它将使材料颜色变为红色,但不会将其恢复为原始颜色。

我的问题是,使用 foreach 还有什么更好的方法来保存原始颜色?

2 个答案:

答案 0 :(得分:0)

好吧,我的猜测是,每次使用GameObject.FindGameObjectsWithTag调用这些方法时,您都在查找对象,而且我很确定没有指定FindGameObjectsWithTag返回的这些对象的顺序,因此每次您都可以更改它调用此方法。该问题最终使您为不同的对象使用不同的原始颜色。我的建议是在objects中获得Start并为数组分配颜色。然后在OnPointerExit函数中使用此数组。

除此之外,您的代码和逻辑对我来说似乎还不错。

答案 1 :(得分:0)

尝试此版本。它基本上执行与您的版本相同的操作,但是请确保在使用颜色阵列之前对其进行初始化(这可能是您的主要问题)。它还保留一份其颜色已被替换的对象列表的副本,这对于创建带有匹配标签的新对象或删除现有对象很重要。最后,它还添加了一些保护措施,以使其在其他地方也要使用ReplaceColors()RestoreColors()时更加强大。

GameObject[] objectsWithReplacedColors;
Color[] originalColors;

public void OnPointerEnter(PointerEventData eventData)
{
    ReplaceColors(GameObject.FindGameObjectsWithTag(myMenu.selected.title), Color.red);
}

public void OnPointerExit(PointerEventData eventData)
{
    RestoreColors();
}

private void ReplaceColors(GameObject[] forObjects, Color withColor)
{
    if (objectsWithReplacedColors != null)    // if there are already objects with replaced colors, we have to restore those first, or their original color would be lost
        RestoreColors();

    objectsWithReplacedColors = forObjects;
    originalColors = new Color[objectsWithReplacedColors.Length];

    for (int i = 0; i < objectsWithReplacedColors.Length; i++)
    {
        originalColors[i] = objects[i].GetComponent<MeshRenderer>().material.color;
        objectsWithReplacedColors[i].GetComponent<MeshRenderer>().material.color = withColor;
    }
}

private void RestoreColors()
{
    if (objectsWithReplacedColors == null)
        return;

    for (int i = 0; i < objectsWithReplacedColors.Length; i++)
    {
        if (objectsWithReplacedColors[i])    // check if the objects still exists (it may have been deleted since its color was replaced)
            objectsWithReplacedColors[i].GetComponent<MeshRenderer>().material.color = originalColors[i];
    }

    objectsWithReplacedColors = null;
    originalColors = null;
}