How can I assign materials using C# code?

I'm trying to assign a material in the Project to a gameobject I create by code. My question is how can I do that directly instead of creating a new Material, asign a shader, textures, etc.

1 Like

Do you mean create a new material from code, or just assign? Your question body & title seem to suggest one and the other respectively.

I mean creating a new material from code, but I already have the answer, thanks

5 Answers

5

Using a material that has already been creaded and using it at runtime without dragging it in the inspector can be done with Resources.Load. Within your Asstest folder you will have to create a Resources folder and place your material there.

// Assigns a material named "Assets/Resources/DEV_Orange" to the object.
Material newMat = Resources.Load("DEV_Orange", typeof(Material)) as Material;
gameObject.renderer.material = newMat;

Keep in mind that Resources.Load() loads na asset at runtime, and is not as fast as instancing a prefab already instantiated somewhere in the scene. If you absolutely must use Resources.Load() you must manage it as to not load the same resource twice, or unload it after every use (non-optimal in most cases).

Also be mindfull that a material which is referenced only in code and not in scene might get stripped from a build.

very heplful ! newer versions of unity will ask to convert the third line to : gameObject.GetComponent<Renderer>().material = newMat;

Then, attach a Physics2DRaycaster instead of a PhysicsRaycaster and attach Collider2D components instead of simple Colliders

Did the script work with the Physics2DRaycaster and Collider2D?

You can set or change the material of an existing GameObject (if the GameObject has a renderer), using the Renderer.material property, like this:

GetComponent<Renderer>().material = newMaterialRef;

Of course using this method means that you need a reference to an existing material, so you need to create one in your Assets (Library) first, and then reference it in your script. You can do this by creating a public variable of type 'Material' like this:

public Material newMaterialRef;

And then dragging a reference of the new material into that variable slot in the inspector.

If you want to create a new material from scratch in code, you can do that too. To do this, you can just create a new Material object like this:

Material myNewMaterial = new Material( shader );

Where 'shader' is a reference to an existing shader to use. The example given in the manual here also has an example where a new shader is created at the same time, from source code included as text.

Hope this is enough to get you started. If you have more specific questions, feel free to ask as a comment to this answer!

Same basic question, but I want to script the part where you 'drag a reference of the new material into that variable slot' - I want to grab an existing material from my assets and assign it all via script.

An update for those using the latest versions of Unity. Using "renderer.material = newMaterialRef;" will cause an error about this being obsolete. This is because you must now access the Renderer component. C# example: Renderer rend = GetComponent<Renderer>(); if (rend != null){ rend.material = newMaterialRef; } And it's best not to GetComponent every loop; see the linked docs page for an example that stores the component reference on Start().

If somebody is searching for this answer recently. This might be useful

    public GameObject box;
    public Material red;
    private void OnTriggerEnter(Collider other)
    {
         if (other.gameObject.tag == "Pickupable")
         {
              box.GetComponent<Renderer>().material = red;
         }
    }

Maybe someone want to explain what is up with this $$anonymous$$ stuff. I see this type of thing all the time. It appears to me, that the developer of this website, needs to allow for this, because this $$anonymous$$ stuff makes the comment almost totally unreadable, or perhaps the person making the comment DOES NOT KNOW how to post the comment (really??? How about that).
Seems to me this comment says:
MeshRenderer renderer = gameObject.GetComponent();
Material materials = new Material[renderer.sharedMaterials.Length;
etc, etc, etc
One can determine that $$anonymous$$ is replacing the M, but why does anyone want to spend time thinking this way? I thought the point was to find answers to questions, and not go thru this SPELLING CRAPOLA

hieshRenderer renderer = gameObject.GetComponent(); $$anonymous$$aterial[] materials = new $$anonymous$$aterial[renderer.shared$$anonymous$$aterials.Length]; for (int i = 0; i < renderer.shared$$anonymous$$aterials.Length; i++) { materials *= my$$anonymous$$aterial; } renderer.shared$$anonymous$$aterials = materials;*

I don't even know what this is, this seems to be new to me. What causes this anonymous thing?

seems like the standard way someone like M$ would use to make compelling to visitors to open an account on the site so that the annoying "this" would be replaced by something meaningful in the name of data protection static public final void this manager constructor binder commutator presenter virtual obfuscator OOP piece a ...

Hurray! Looks like Unity finally reverted $$anonymous$$ strings when they moved over to the new Discussions website! I can read the code in other posts fine! Of course, the ones in this post are still there because they were originally written this way.

What if your model has more than one material slot? I have a robot hand with two materials that I need to swap via code. (I appreciate any answers ahead of time, ya’ll rock)

I had this problem today as well and the solution is that you need to create an array of materials and assign it to the renderer after that. My code looks something like this: MeshRenderer renderer = gameObject.GetComponent(); Material[] materials = new Material[renderer.sharedMaterials.Length]; for (int i = 0; i < renderer.sharedMaterials.Length; i++) { materials *= myMaterial;* *}* *renderer.sharedMaterials = materials;* I need every Material to be the same Material, but you could make the array manually and choose different ones for the different slots