diem_L
diem_L

Reputation: 399

Get material from assets

In my Unity Project I try to highlight some object with some self-made material. Unfortunately the codes I found does not work.

The following script is added to three different GameObjects:

Renderer[] rend_ThisObject;
Material white, red;

void Start()
{
    // I tried the following two code parts:
    white = Resources.Load<Material>("White");
    white = Resources.Load("Material/White.mat", typeof(Material)) as Material;

    red = Resources.Load<Material>("Red");
    red = Resources.Load("Material/Red.mat", typeof(Material)) as Material;           
}

void Update()
{
    foreach (var child in rend_ThisObject)
    {
        child.material = blinkObject ? white : red;
    }
}

If I run the project the game objects with the script appears in pink and do not blink.

If I change the Material white, red; to public Material white, red; it works fine. What do I have to change to get the materials from my assets/resources/material folder?

Upvotes: 2

Views: 8371

Answers (1)

derHugo
derHugo

Reputation: 90629

In general:

From Unity's own Best practise for Resources:

Don't use it.

What was wrong with simply using your public fields and set them via the Inspector?

If you don't like them to be public then simply use [SerializeField]

[SerializeField] private Material white;
[SerializeField] private Material red;

instead and assign them via the Inspector!


Then assuming your path is not assets/resources/material but rather Assets/Resources/Material see Resources.Load!

You tried

white = Resources.Load<Material>("White");
white = Resources.Load("Material/White.mat", typeof(Material)) as Material;

Both are wrong:

  • The first time it is missing the folder path

    The path is relative to any folder named Resources inside the Assets folder of your project

  • the second has the file ending too much.

    Note: Extensions must be omitted.

So for loading the file with path

Assets/Resources/Material/White.mat

it should simply be

white = Resources.Load<Material>("Material/White");

Now another general note:

Doing this blink on a per frame basis is not a god idea!

Rather use some sort of delay like e.g.

// adjust via the Inspector as well
[Tooltip("Color changes per second")]
[SerializeField] private float blinkFrequency = 2f;

private float timer;

void Update()
{
    timer -= Time.deltaTime;
    if(timer <= 0)
    {
        timer = 1 / blinkFrequency;

        blinkObject = !blinkObject;
        foreach (var child in rend_ThisObject)
        {
            child.material = blinkObject ? white : red;
        }
    }
}

Upvotes: 11

Related Questions