Unity - массив материалов обратно к исходному объекту - PullRequest
0 голосов
/ 14 сентября 2018

Так что в Unity я в настоящее время делаю некоторую функцию выбора / наведения, чтобы цвет объекта изменялся, если вы наводите курсор на него, и изменяете назад, когда мышь больше не находится над объектом.Так что проблема в том, чтобы положить материалы обратно.

У меня есть объект с большим количеством детей / внуков / детей младшего возраста (?).Итак, сначала я получаю дочерние объекты через цикл foreach.Затем я получаю материалы, также через цикл foreach, в массиве baseMaterials.В моей функции обновления я изменяю материал объектов на «hoverMaterial».

Но мой вопрос в том, как мне заменить 'hoverMaterial' обратно на 'baseMaterials'?

private void Awake()
{
    // Get children objects with renderers, skip empty objects without renderers
    List<GameObject> objectChildrenList = new List<GameObject>();
    foreach (Transform child in transform)
    {
        if (child.GetComponent<Renderer>())
            objectChildrenList.Add(child.gameObject);

        foreach (Transform grandChild in child)
        {
            objectChildrenList.Add(grandChild.gameObject);
        }
    }
    objectChildren = objectChildrenList.ToArray();

    // get from children objects the color 
    if (objectName.transform.childCount > 0)
    {
        List<Material> objectColors = new List<Material>();
        foreach (GameObject objects in objectChildren)
        {
            var objectMat = objects.GetComponent<Renderer>().materials;
            foreach (Material m in objectMat)
            {
                objectColors.Add(m);
            }
        }
        baseMaterials = objectColors.ToArray();
    } else {
        baseMaterial = objectName.GetComponent<Renderer>().material;
    }
}

private void Update()
{
    if (gameManager.selectedObject != this.gameObject)
    {
        if (mouseOver)
        {                
            if (objectName.transform.childCount > 0)
            {
                foreach (Transform child in transform)
                {
                    if (child.GetComponent<Renderer>())
                        child.gameObject.GetComponent<Renderer>().material = hoverMaterial;

                    foreach (Transform grandChild in child)
                    {
                        grandChild.gameObject.GetComponent<Renderer>().material = hoverMaterial;
                    }
                }
            } else {
                objectName.GetComponent<Renderer>().material = hoverMaterial;
            }
        } else {
            if (objectName.transform.childCount > 0) {
                // Put baseMaterials back
            } else {
                objectName.GetComponent<Renderer>().material = baseMaterial;
            }
        }
    }       
}

1 Ответ

0 голосов
/ 14 сентября 2018

Единственный способ сделать это - использовать словарь, афаик.Причина этого в том, что если вы сохраните Материалы в виде списка, количество GameObjects в сцене может измениться к тому времени, когда вы прекратите зависание, и список, который вы сохранили, больше не будет совпадать с фактическими материалами GameObjects.Поэтому вам нужно знать, какие материалы принадлежат какому Renderer / GameObject.Словарь дает вам это.

Так что я бы использовал Dictionary<Renderer, List<Material>>.Когда вы начинаете зависать, вы перебираете все объекты GameObject с рендерами, которые хотите изменить, и сохраняете их в словаре.Тогда вы меняете материалы.Когда зависание останавливается, вы перебираете словарь и возвращаете материалы обратно.


Обратите внимание, что если все, что вы хотите изменить, это цвет, тогда лучше использовать MaterialPropertyBlock .Вы можете использовать MaterialPropertyBlock.SetColor , вам просто нужно знать, какое свойство цвета названо в шейдере.Обычно это _Color, вы можете проверить, посмотрев материал в Инспекторе в режиме отладки.Преимущество использования MaterialPropertyBlock заключается в том, что вы не будете генерировать дополнительный вызов отрисовки.Это просто лучший способ сделать это.

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