I’m moving my first steps in Unity and scripting. I’ve managed to get some basic functions done via either scripting or Unity’s GUI, but I’ve hit a wall while trying the next step.
I have built a model in 3ds Max; the model itself is composed by several objects. These objects are assigned a Multi/Sub-Object material. Everything has been exported via FBX and Unity imports everything as a single entity, which I’m happy with as it simplifies managing the scene.
I’ve created several materials in Unity and then assigned them to the imported model, and everything displays correctly in the viewport.
Now I want to change a material when I press the button. For example, the material “acliv fuselage Blend” (name of the material in 3ds Max) has the Unity material “MatFuselageStandard” applied, but when I click a button I want it to swap with another material (let’s say “MatFuselageStructure”).
And this is where I get lost, I can assign basic functions to a button but changing assignment to a material is completely over my head.
How can I achieve this?
Just to double check, do you mean you want to do this within your game, while it’s running? Or do you want to make a custom editor to use within Unity itself to change the materials? I’m assuming it’s the first one…
The general approach here is that you just need to access the object’s MeshRenderer or its SkinnedMeshRenderer, whichever it has, and then access to materials' property of it. You can modify the contents of the
materials’ array to reference whatever materials you want, and then assign that array back into the renderer’s `‘materials’ property to update the renderer to use that material. Keep in mind this is a runtime-only change, which will revert when you stop playing.
Something like this:
public Renderer MyRenderer;
public void SetMaterial(Material mat, int index) {
var mats = MyRenderer.materials;
mats[index] = mat;
MyRenderer.materials = mats;
}
The complicated part for your model will be getting the right index, since you have so many materials.
Thanks for the reply.
Yes, the change will be at runtime.
However…I’m still quite lost.
I’ve created a script asset, and attached it to the button. In the script component I pick one polygonal model.
Then I create a new event in the On Click () window, pick the script, and the only option I have is Monoscript, and then I pick the material I want. However, if I run the game nothing happens when I click on the button, and I see the inspector is showing different stuff.
I was able to have one material change, which is great progress 
However I need to change other two materials in the same model as well, but if I add the action in the Inspector tonly the first material changes.
[edit] A bit more info:
I want to be able to switch paint scheme on an aircraft. Right now I’m testing with two, called Standard and Structure.
Each paint scheme is composed by two materials, one for the wings and one for the fuselage.
The aircraft in Unity is composed by three objects: the airplane, landing gear up, and landing gear down. I switch landing gear up/down with another button.
All 3 components use multiple materials imported from a Multi/Sub-Object material from 3ds Max; in Max these material all have the same ID.
With the paint scheme button I need to change materials to the airplane and the two landing gear positions.
I was able to change the fuselage material on the airplane but not on the landing gear, nor have the wing material change on the aircraft.
Show the code you’re using that actually assigns the materials. Your last screenshot doesn’t tell me much, only that you set up a click handler on a button.
Note that a Renderer has two different properties, material' and
materials’. The first takes a single material, the second takes an array of materials. If you set material', it will only change the first (index 0) material on the renderer. To change the rest of the materials, you need to create an array of materials and assign it to the renderer's
materials’ property.
See my earlier code sample, which should work, as long as you’re passing in the correct index along with the material.
I’m using the code you provided in the first reply without changes…as said before I’m moving the first steps into coding so arrays are still a bit too advanced for me 
Anyway, the only material-related picks I have in the MeshRenderer inspector are “Material material” and “Material sharedMaterial”.
Well, if a renderer has multiple materials, the only way I know of to programmatically adjust the materials at runtime is to use the `materials’ property, as I’ve already shown:
You need to know the correct material index. Your ChangeMaterial script will need to specify the material index you’re changing.
As what I’m doing is a side project and learning how to properly code was taking way too much time I resorted to a more brute-force approach…I divided all 3D models into the relevant materials and added single on click actions to change materials individually.
It might not be particularly classy but it works.
Thanks for the support.