Load, change material to game object II (not a repeat)

I am toggling 2 materials on 1 object's 1 element Array.

The code works, even the line I noted as (***) Please someone comment as to why that line(***) in the code can be swapped instead of the line above it without any repercussions? (not directly related but a strange quirk, at least to me.)

3 questions, all related to changing/loading a material on a game object.

I have read the various posts that cover how to change a material or texture without going to disk, but nothing I tried worked, I even read one that claims that the entire materials array in the renderer must be copied, no element can be written?

Here is how I did it:

Q1 - I am not sure this is the best way to accomplish the task, but if I use this code, it works perfectly well and no speed problem occurs on the local dev machine. Will it be a problem on a web based scenario? (i.e.: the material will need to come down from the HOST)

CODE: I hope this code may help someone else... it works flawlessly. I had to create a Resources folder: Assets/Resources and put both materials in it. The trigger object has its collider set as 'Is Trigger'. The renderer object has no collider. I know 'material' points to the 1st element of the materials Array.

function OnTriggerEnter (TriggerObject : Collider)
    var thisrenderer = gameObject.Find("RendererObject").GetComponent(Renderer);
    var mat : Material;
    if (thisrenderer.material.name == "Material1 (Instance)") {
        mat = Resources.Load("material2");
    } else {
        mat = Resources.Load("Material1");
    }
    thisrenderer.material = mat;
    //thisrenderer.renderer.material = mat;  (***) <- this line should fail, but it works just the same as the line above it???.

    //DEBUG:
      print ("ArrayLen: " +thisrenderer.materials.Length + " -" +thisrenderer.material.name);
}

I took a peek at this post. It does a similar task with textures on the current object [ http://answers.unity3d.com/questions/17195/load-material-to-gameobject ][1]

Q2 - Could someone explain how to accomplish the same task without going to disk? Where would the source materials be stored... in not used/displayed stub objects? or do they have to be loaded into an array as done above in the Start or at game/scene Load?

Q3 - How will the materials be toggled into the array?... the same as in the code above? thisrenderer.material = mat;... except perhaps mat[x];

UPDATE: This code allows to draw from a material list to change the material on a GameObject without going to disk as the example above does. May not be the best way to accomplish this task. (see my comment in skovacs1's answer)

The 'MaterialsMY' gameobject is solely used to store the materials in its only component, a disabled Renderer(so it does not draw in the scene).

function OnTriggerEnter (TriggerObject : Collider) {
    var DestRenderer = gameObject.Find("DestRendererObject").GetComponent(Renderer);
    var SrcRenderer = gameObject.Find("MaterialsMY").GetComponent(Renderer);
    if (matName.IndexOf("Material1") >= 0) {
        DestRenderer.material = SrcRenderer.materials[1];
    } else {
        DestRenderer.material = SrcRenderer.materials[0];
    }
 //print ("ArrayLen: " + DestRenderer.materials.Length + " - " +DestRenderer.material.name);
}

As per the FAQ, break your questions into separate questions. It's hard to answer UnityAnswers questions which ask more than one thing at a time.

About your commented line of code: renderer is an inherited variable shared by all GameObjects and Components and Behaviours and Renderer happens to be a Component so it inherits this property. You have an instance of a Renderer and you then try to access its renderer which just so happens to be itself in this case. There is nothing wrong with it despite being convoluted and there is no reason for it to fail. You could even write renderer.renderer.renderer.renderer.renderer.renderer.renderer.renderer and it is still going to return you the same Renderer as renderer would and it will still be valid.

Q1. Resources.Load loads from a Resources folder. If there is no asset at the path specified in the path to the Resources folder, it will fail to give you the asset you are trying to load. This means that you will have to make this call on the server and then send the result to the client or else they would all have to have the material and Resources folder. This shouldn't be a problem, but you should test across an actual networked environment as there may well be latency and other concerns. I'm not entirely knowledgeable about your server setup so I cannot provide an authoritative answer as to where your changes will propagate to and from.

Q2. If you were to store a reference to the material in your script in stead, you wouldn't have to keep loading them and if you set the reference in the editor, you wouldn't need Resources.Load at all as the materials would be built into the application's data. The reference can simply be some public variables that store the materials. Since this builds into the application data, I would believe that the material is distributed with the build to all of the clients however.

var foo : Material; //set this in the editor
var bar : Material; //set this in the editor

function OnTriggerEnter (TriggerObject : Collider)
    var thisrenderer = gameObject.Find("RendererObject").GetComponent(Renderer);
    if(foo && thisrenderer.material.name == "Material1 (Instance)")
        thisRenderer.material = foo;
    else if(bar) thisRenderer.material = bar;
}

Q3. Materials will not be swapped, but rather assigned or replaced. To implement swapping, you would have to store the old value of one of them temporarily. If you are using multiple materials, you would index the array(s) at the indices you want to change and change them (as they are public writable variables after all). To swap materials in the array(s) (not the intended use I believe), it would be something like:

var temp : Material = renderer.material;
renderer.material = renderer.materials[1];
renderer.materials[1] = temp;

the materials and sharedMaterials arrays are meant for meshes whose submeshes use separate materials (each with a separate triangle list) (see this).