Измените все материалы средства визуализации на один материал

#c# #unity3d

Вопрос:

У меня есть несколько визуализаторов сетки, большинство из них содержат более 2 или 3 материалов. Я хочу, чтобы все материалы для визуализации сетки были переключены на один материал, а затем снова переключились на его старые материалы. Как мне это сделать?

 public MeshRenderer[] renderer;
public Material switchMat;

private void Start () {
        for (int i = 0; i < renderer.Length; i  ) {
            renderer[i].materials[i] = switchMat; //Switch to new Material - not working
        }
    }

private void SwitchBack(){
      for (int i = 0; i < renderer.Length; i  ) {
            //Switch back to original Material
        }
    }
 

Ответ №1:

Во-первых, вы переключаете только один материал для каждого визуализатора оба раза, используя i его в качестве индекса. Вам нужно будет иметь два цикла, один для перебора всех визуализаторов, другой для просмотра всех материалов текущего визуализатора!

И тогда вы, вероятно, могли бы просто хранить оригинальные материалы в Dictionary таком

 private Dictionary<Renderer, Material[]> _originalMaterials = new Dictionary<Renderer, Material[]>();

private void Start () 
{
    // Iterate through all renderers
    foreach (var rend in renderer) 
    {
        // store a copy of the array linked to this renderer
        _originalMaterials.Add(rend, rend.materials);

        // get the current (original) materials instances
        // Renderer.materials returns a new copy of the array every time
        var materials = rend.materials;

        // in the local array simply replace all elements
        for(var i = 0; i < materials.Length; i  ){
            materials[i] = switchMat;
        }

        // assign back the entire materials array
        rend.materials = materials;
    }
}

private void SwitchBack()
{
    // Iterate through all renderers
    foreach (var rend in renderer) 
    {
        // Check if for current renderer there is an entry in the dictionary
        if(_originalMaterials.TryGetValue(rend, out var materials))
        {
            // if so assign back the entire original array
            rend.materials = materials;
        }
    }
}
 

Комментарии:

1. К сожалению, не все материалы возвращаются в рендерер. Только первый из них назначается обратно в функцию SwitchBack ().

2. У меня есть 3 визуализатора и 6 материалов. 2 визуализатора имеют 3 и 2 материала соответственно. В функции SwitchBack() только первый визуализатор возвращает исходный материал. Но все остальное остается прежним. Оператор if f(_originalMaterials.TryGetValue(rend, out var materials)) вызывается только один раз.

3. Если вы зададите точку останова в SwitchBack методе, сколько записей _originalMaterials будет и сколько элементов будет во renderer время Start и во SwitchBack время ?

4. Да, я пытался это сделать. Я добавил журнал раньше if(_originalMaterials.TryGetValue(rend, out var materials)) , и журнал печатается 6 раз из-за 6 материалов. а затем я добавил журнал внутри оператора if, и он печатается только один раз, так как материал назначается только первому визуализатору.

5. and the log prints 6 times because of 6 materials .. нет, этого бы не случилось … он должен печататься один раз для каждого визуализатора , а не материала.