Unity Изменение цвета материала на нескольких игровых объектах - PullRequest
0 голосов
/ 10 марта 2019

Я создал меню правой кнопки мыши, и я хочу, чтобы объекты меняли цвет материала, в то время как моя кнопка мыши находится в этом меню.

Это код:

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

С первым циклом for он вообще не работает, но без него, когда я помещаю свою мышь в кнопку, он делает цвета материала красным, но не меняет его обратно на оригинальный.

У меня вопрос, есть ли лучший способ сохранить оригинальные цвета с помощью foreach ?

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

Попробуйте эту версию. По сути, он делает то же самое, что и ваша версия, но перед использованием его обязательно инициализирует массив цветов (что, вероятно, было вашей основной проблемой). Он также хранит копию списка объектов, цвета которых были заменены, что важно в случае создания новых объектов с совпадающим тегом или удаления существующих. Наконец, он добавляет несколько мер безопасности, чтобы сделать его более надежным в случае, если вы хотите использовать 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;
}
0 голосов
/ 10 марта 2019

Что ж, я думаю, вы находите объекты каждый раз, когда эти методы вызываются с помощью GameObject.FindGameObjectsWithTag, и я уверен, что порядок этих объектов, возвращаемых FindGameObjectsWithTag, не указан, поэтому он может меняться при каждом вызове этого метода.Эта проблема в конечном итоге дает вам разные оригинальные цвета для разных объектов.Мое предложение будет получить objects в Start один раз и назначить цвета для массива.Затем используйте этот массив в функции OnPointerExit.

Кроме этого, ваш код и логика кажутся мне подходящими.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...