- Home /
Change material during runtime c#
Hi ive spent the entire day looking for a solution but can't find anything.
I have a chair (single mesh), with 3 materials on it, assigned to the 3 sub mesh components, as exported from max.
Now i want to change the color of lets say the white plastic from an interface palette, much like https://youtu.be/admsmCmaL3Y?t=55.
I started out basic with: if (Input.GetKey (KeyCode.A)) gameObject.GetComponent().material.color = Color.red
But this chooses a random material and changes that to red, so i cant specify which one relates to which From reading around, I found an array can possibly do this (the material change part, I know the palette GUI is a separate task), but I have no idea how to construct the full this script (artist not coder)
So far i found:
Material[] mats; mats = renderer.materials; mats[1] = theNewMaterial renderer.materials = mats;
But im not sure how to put this in the script correctly.
using UnityEngine; using System.Collections;
public class ChangeColor : MonoBehaviour {
public Material[] mats;
void Update ()
{
mats = GetComponent<Renderer>().materials;
mats[1] = theNewMaterial;
GetComponent<Renderer>().materials = mats;
}
}
As much as I know about C# at the moment, thus a bit lost as I get error CS0103: The name `theNewMaterial' does not exist in the current context and not sure how to ref that properly
Then I would also be looking at how to do the swapping via the interface palette as a second objective :)
Thanks
Answer by BiG · Jul 21, 2015 at 07:19 AM
The approach is correct, but theNewMaterial
is an undefined variable. You should initialize it as an exposed variable, as you did with mats
.
public Material theNewMaterial;
Then, through the Inspector, drag and drop a Material from your project to the variable's value.
EDIT:
You can have three exposed variables identifing materials:
public Material plastic;
public Material wood;
pubblic Material metal;
Then, when you have to assign them at the chair:
mats = GetComponent<Renderer>().materials;
//Here, you have to assign with the exact order!
mats[0] = plastic;
mats[1] = wood;
mats[2] = metal;
GetComponent<Renderer>().materials = mats;
Hi Big, thanks for the input, that worked, but it still just changes one of the components at random, in this case the legs to the new material.
How do I tell it which component refers to which material or set of material options that the user can choose from?
As I mentioned it has 3 materials on it, plastic, wood and metal. Single mesh
thanks
@ptblk: Hi, I have updated my answer. Since you are extracting an array of materials from the chair Object, you should "refill" it with all the possible values. I hope that my modified answer could help you a little bit.
Answer by sas_88 · Jul 21, 2015 at 10:06 AM
Assign the materials in array as u did and get the materials present in the object n assign to it.
count = 0;
foreach(Renderer r in GetComponentsInChildren<Renderer>())
{
r.material=mats[count];
count+=1;
}
Sorry can you be more specific. Assume I know very little which is true, so when you give me this code, i have very little idea of what to do with it. So far I have big's code as such:
using UnityEngine; using System.Collections;
public class ChangeColor : $$anonymous$$onoBehaviour { public $$anonymous$$aterial[] mats;
public $$anonymous$$aterial plastic; public $$anonymous$$aterial wood; public $$anonymous$$aterial metal;
void Update ()
{
mats = GetComponent<Renderer>().materials;
//Here, you have to assign with the exact order!
mats[0] = plastic;
mats[1] = wood;
mats[2] = metal;
GetComponent<Renderer>().materials = mats;
}
}
Although this doesnt really do anything except change the materials by default when I play the scene.
What i need is that when i click on one of the 3 areas of the chair, that part will change material to one of the specified materials in the array if that makes sense. So if I click the plastic seat it will change and loop to the say 3 colors of plastic i have assigned.
Thanks
Hi ptblk, I'm trying to do somthing similar, did you solve the problem? if yes could you show the full script? thanks
Answer by unity_DrG5KGGUgbmWwA · Mar 11, 2018 at 08:18 PM
Hi all,
Is this chat still live, i have a similar question to finish off my project.
Your help would be most appriciated.
Thanks and hope to hear from you soon.
Curtis
Answer by jaspercayne · Apr 19, 2016 at 05:01 AM
Probably the best bet will be to raycast at the chair or create buttons that completely envelop the interchangeable parts. Then on a button press or a ray hit you would just set the current material to be the next one in the list, or if you are at the end of the list loop back around to the beginning again.
I can post something of an example of it is needed, but I take no responsibility for inefficient or unoptimized code.
Answer by MagyarPeter · Feb 06 at 12:21 PM
You cannot change the materials one by one, you have to replace the entire material[] array:
public Renderer r;
public Material newMaterial;
void changeMat()
{
//this code creates a copy of the original material array, replaces the first element with the
//"newMaterial" then assigns the new amterial list to the renderer
Material[] newMats = new Material[r.materials.Length];
r.materials.CopyTo(test, 0);
newMats[0] = newMaterial;
r.materials = newMats;
}
//I use this code to replace my character's materials when it dies, it should work