4

I want to change and set 3 things after setting the new material:

First The shader type to Unlit/Color

Second The albedo color to change it for example to: 255,0,0,255

Third The metallic value from 0 to 1

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DoorsLockManager : MonoBehaviour
{
    public bool locked;
    public Color lockedColor = Color.red;
    public Color unlockedColor = Color.green;
    public Renderer rend;

    private GameObject[] doorPlanes;

    private void Start()
    {
        doorPlanes = GameObject.FindGameObjectsWithTag("DoorPlane");

        for (int i = 0; i < doorPlanes.Length; i++)
        {
            rend = doorPlanes[i].GetComponent<Renderer>();
            if (locked)
            {
                rend.material.SetFloat("Metallic", 1);
                rend.material.color = lockedColor;
            }
            else
            {
                rend.material.color = unlockedColor;
            }
        }
    }

    // Update is called once per frame
    void Update ()
    {

    }
}

This line does nothing:

rend.material.SetFloat("Metallic", 1);

This is what I want to change:

Material/Shader

Programmer
  • 121,791
  • 22
  • 236
  • 328
Benzi Avrumi
  • 937
  • 1
  • 8
  • 24

1 Answers1

7

When you need to change a shader property but you don't know what to use for the proper name to use, select the material, click on its settings icon then click on "Select Shader". From there, you will see all the shader property names and their types and you will know which function and name to use to change the shader's properties.

enter image description here

With the default standard shader it looks something like this:

enter image description here

You need to know this otherwise you would need to ask new question for each property you want to change.

Your Renderer reference:

public Renderer rend;

To set it, the SetXXX function is used:

rend.material.SetFloat("_Metallic", 1); //Metallic is a float

To get it the GetXXX function is used:

float metallic = rend.material.GetFloat("_Metallic"); //Metallic is a float

To change or get the The albedo color to 255,0,0,255.

rend.material.SetColor("_Color", new Color32(255, 0, 0, 255));
Color color = rend.material.GetColor("_Color");

Notice that I used Color32 instead of Color because Color32 takes values between 0 and 255 while Color expects values between 0 and 1.

To change the material's shader to "Unlit/Color", just find it then assign it to the material:

Shader shader = Shader.Find("Unlit/Color");
rend.material.shader = shader;

Note that the "Unlit/Color" shader doesn't have the _Metallic property. It has one one property and that is "_Color". You can use the first method I described to determine which properties it has before attempting to change them.

What if the shader is used on many different objects. I want all the objects to change when the property is changed on one of them.

To change all the objects using the-same material, use Renderer.sharedMaterial instead of Renderer.material. The shared material changes the original material and every other objects should pick that new material up as long as you have not called Renderer.material on the material which actually makes a new copy for the said material and disconnects the renderer material from the original material.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • For the Color I did this before your answer I used only Color like this: rend.material.color = new Color(255,0,0,255); And it's working fine. Just wondering since I didn't use Color32 – Benzi Avrumi Oct 22 '18 at 08:22
  • 1
    Nope. That's an undefined behavior. It may work and may not depending on the values and that's because of the reason I mentioned in my answer. There are tons of questions about this particular issue on this site. Just be aware of this. You can still use `Color` with the 0 to 255 range but you must divide the values by 255f. `rend.material.color = new Color(255/255f,0/255f,0/255f,255/255f)` – Programmer Oct 22 '18 at 08:29
  • Thanks for the answer and comments. – Benzi Avrumi Oct 22 '18 at 08:45
  • Does this change all the materials using this shader, or just the one? – Confused Nov 30 '18 at 06:46
  • @Confused You mean you have more than one material on the MeshRenderer and want to know if that changes the first material or all of them on the MeshRenderer ? – Programmer Nov 30 '18 at 06:49
  • No. The opposite. The shader is used on many different objects. I want all the objects to change when the property is changed on one of them. – Confused Nov 30 '18 at 07:03
  • 1
    I've edited the answer to add that information for you – Programmer Nov 30 '18 at 07:21
  • Ruddy Brilliant!!! @Programmer THANK YOU. I am constantly amazed. Looking forward to writing the forward for your book on Unity. – Confused Dec 02 '18 at 03:32
  • @Programmer Challenge for your UberMind. May need a new question. Any way to change this sharedMaterial and its properties in an Animation Clip in the Unity Editor's various 'timelines'? I favour using Legacy Animation Component and its Animation Clips, but so long as it works in an Animation clip it should work in Legacy, Animator and Timeline. I've become somewhat savvy with these things, mainly because using them can help me avoid writing a lot of code. – Confused Dec 02 '18 at 04:41
  • I really don't know. I do my animation stuff through code and coroutines since it gives me more control. You really should be using the Animator compone because the other one can be removed anytime. It has been 4 years since its deprecation. – Programmer Dec 02 '18 at 06:40