Loop through all materials in scene and change them

Is there a way to access the materials in a scene at runtime, and reassign them?

you would need the game objects you want to change, then you can set the gameObject.renderer.material or gameObject.renderer.materials[] for multiple materials if necessary.

Hi,

There is much better built in alternative.

Camera.RenderWithShader

Bounce from this page for other types of similar features.

If you are looking exchanging different materials etc etc, then you'll have to do it manually, and I would recommend doing a reusable component for it using GetComponentsInChildren(); to retrieve all renderer of that game Object and its childrens, then you can store material references, exchange them at will etc etc. I do that for example, when I need to hide parts of an assembly, I have a transparent shader that I swap at runtime.

If you need a more exhaustive description of such component, say so, and I'll wrap up something.

[EDIT] here is a component to do just that:

using UnityEngine;
using System.Collections;

public class MaterialSwitcher : MonoBehaviour {

    public Material switchMaterial;

    private Hashtable _matList = new Hashtable();

    private Renderer[] _renderers;

    private bool switched;

    /// <summary>
    /// Record all material of the gameobject and its children
    /// </summary>
    void Start () { 
        _renderers= GetComponentsInChildren<Renderer>();
        foreach( Renderer _renderer in _renderers){
            _matList.Add(_renderer,_renderer.material);
        }
    }

    /// <summary>
    /// just for testing
    /// </summary>
    public void Update(){

        if (Input.anyKeyDown){
            ToggleMaterial();
        }
    }

    /// <summary>
    /// Toggle between the switch material and the default.
    /// </summary>
    public void ToggleMaterial(){
        switched = !switched;
        if (switched){
            SwitchMaterial();
        }else{
            ResetMaterial();
        }
    }
    /// <summary>
    /// Revert to the default material
    /// </summary>
    public void ResetMaterial(){
        switched = false;
        foreach( Renderer _renderer in _renderers){
        _renderer.material = _matList[_renderer] as Material;
        }
    }

    /// <summary>
    /// Switch to the predefined switchMaterial
    /// </summary>
    public void SwitchMaterial(){
        switched = true;
        SetMaterial(switchMaterial);
    }   

    /// <summary>
    /// If you want to assign an arbitrary material
    /// </summary>
    /// <param name="mat">
    /// A <see cref="Material"/>
    /// </param>
    public void SetMaterial(Material mat){
        switched = true;
        if (mat==null){
            Debug.LogWarning("no Material defined to set on GameObject: "+name);
            return;
        }
        foreach( Renderer _renderer in _renderers){
            _renderer.material = mat;
        }
    }

}

Bye,

Jean

I agree with Jean, I think that for each object that you want to switch materials, you should add a component on that object that will perform the switch. This component can look maybe like:

public Material NewMaterial;

public void Awake()
{
    renderer.material = NewMaterial;
}

If you need to have a more complex logic to choose between multiple materials, you can add it to this class and change the material to the desired one. This more distributed approach seems more in the Unity way of doing things, which I like alot ;p

-- David