I'm a total newcomer to unity and I was just wondering how to set a material from C#?
I have a prefab model and I can change the texture from the editor no problem. What I want to do is randomly set the material when an instance of the prefab is generated.
Here is the field I want to change:
And I am creating these with the following code:
Instantiate(eggPrefab, spawnPos, Quaternion.identity);
(Where eggPrefab is a public Transform).
I hope that is enough information!
Thank you.
After you instantiate the GameObject, get the MeshRenderer from it then change it's material:
public GameObject eggPrefab;
public Vector3 spawnPos;
public Material mat;
void Start()
{
GameObject obj = Instantiate(eggPrefab, spawnPos, Quaternion.identity);
obj.GetComponent<MeshRenderer>().material = mat;
}
If you don't have the material then you can create one with a shader and assign it to the MeshRenderer:
GameObject obj = Instantiate(eggPrefab, spawnPos, Quaternion.identity);
//Find the Standard Shader
Material mat = new Material(Shader.Find("Standard"));
//Set Texture on the material
//mat.SetTexture("_MainTex", yourTexture);
obj.GetComponent<MeshRenderer>().material = mat;
Finally, if you have more than one material then use the materials
property instead of the material
property and assign your array of material to it:
GameObject obj = Instantiate(eggPrefab, spawnPos, Quaternion.identity);
//Find the Standard Shader
Material mat = new Material(Shader.Find("Standard"));
//Set Texture on the material
//mat.SetTexture("_MainTex", yourTexture);
//Create array of mats (Create one for example)
Material[] mats = new Material[1];
mats[0] = mat;
obj.GetComponent<MeshRenderer>().materials = mats;
Edit:
I missed the random part. If you want random material selection, just use Random.Range
to select one item from the array of Material.
public GameObject eggPrefab;
public Vector3 spawnPos;
public Material[] mats;
void Start()
{
GameObject obj = Instantiate(eggPrefab, spawnPos, Quaternion.identity);
int matIndex = UnityEngine.Random.Range(0, mats.Length);
obj.GetComponent<MeshRenderer>().material = mats[matIndex];
}
I think mixing the random material behaviour with creation behaviour is overcomplicating things. Just create a component that randomises a GameObject's material on Start and it will run when you instantiate your prefab.
public class MaterialRandomiser : MonoBehaviour {
[SerializeField]
private Material[] _materials;
[SerializeField]
private Renderer _renderer;
public void Start () {
ChangeMaterial();
}
public void Reset () {
_renderer = GetComponent<Renderer>();
}
public void ChangeMaterial () {
_renderer.material = SelectRandomMaterial();
}
private Material SelectRandomMaterial () {
return _materials[Random.Range(0, _materials.Length)];
}
}
Attach it to your prefab and now when you spawn them, they will have random materials. You now also have the option to use the same code on non-prefab objects as well. Just don't forget to assign the materials!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With