Cannot implicitly convert type UnityEngine.MeshRenderer to UnityEngine.Material.

Hello!
First off: I’m a noob.
I’m trying to make a gameobject fade away before destroying itself by using Color.Lerp but I keep getting this compile error.

I think I understand what this error means: I’m asking Unity for a Material and all it knows how to give me is a MeshRenderer. I’m not sure how to fix it. I’ve gone through several questions on here and nothing really seems to help. I understand that I’d probably need to do a cast, but other than that (syntax, etc) I’m lost.

I’m also getting No Overload for SetColor takes 1 argument.

Here’s my code:

 void Start () {
	Material myMat = GetComponent<MeshRenderer>();
 }

 void FadeOut(){
	Color matColor = myMat.color;
	     for(float i=0; i<1; i+=Time.deltaTime/lerpTime){
            myMat.SetColor(Color.Lerp(matColor, Color.clear, i));
	}
}

I appreciate any advice you have for me!

I’ll tell you where the problem is, but first off: This is basic coding understanding. It seems you are trying to get the code bits you need and somehow connect them without the basics for that. I recommend going through some beginner tutorials like this rather than code examples. The tutorials will cover things like this.

Anyway, about your problem.

As the error message states, GetComponent<MeshRenderer>() returns the reference to a MeshRenderer. And your variable that you declared on the left has the type Material, which is not the same type. It’s like someone asking you how many hamburgers you want (a number) and your anwer is “Potato”. Computers are just as confused as humans about such answer.

You guessed that you need a cast or something, but a cast means making a value be of another type. Casts are for when you, for example, calculated that you need 3.000 hamburgers, but you don’t want a floating point number because the guy at the drive-in wants an integer. So you cast that 3.000 to 3. Still the same value. However, you’re trying to cast “potato” to 3. That’s not really working.

Instead, you need to know what you are trying to do. A MeshRenderer, like all other classes, consists of properties and methods. They can be looked up in the Scripting Reference. The page for MeshRenderer is here.

As you can see, there is a property called “material”, and the description says that it indeed refers to the primary material that this MeshRenderer has. As you apparently know (looking at myMat.color here), calling methods and using properties of an object works with the dot operator. So if you want the material value from your MeshRenderer it’s

GetComponent<MeshRenderer>().material

Instead of trying to interpret the MeshRenderer as a material, which it simply isn’t, you have to ask it for its material property.

So, that’s one problem. The next is that variables only exist in the scope they are declared in. Roughly speaking, that means the set of { }s the declaration is in. You declare myMat in Start, so it only exists in Start. Thus, you cannot use it in FadeOut. Instead, you need to delcare it globally for your whole class. Works like this:

private Material myMat; // Declare here

void Start()
{
  myMat = GetComponent<MeshRenderer>().material; // Set the value here
}

Then you can use it in FadeOut as well, because the scope myMat is in now is the whole class.

Next up, you mentioned that SetColor doesn’t work. With what you learned about the Scripting Reference, you maybe guessed that this is where to look up what’s wrong. Here’s the page for Material.SetColor. You can see that there’s two parameters needed for both possible versions:

public void SetColor(string name, Color value);

public void SetColor(int nameID, Color value);

Why is there a name (or ID) needed? The answer to that is: Materials can have multiple color values. The standard shader, for example, has one color for the diffuse surface, and another color value for light emission. So which of the colors do you want to change here? Unity needs to know.

The name you need to enter depends on the shader you are using. Click your material, and in the very top right of the inpector, click the little cog, then “Select Shader”. You have a very high chance of the color property’s name being _Color. So it’s

myMat.SetColor("_Color", someColor);

but _Color changes can be shortened using the color property:

myMat.color = someColor;

Then, finally, you have another problem. Your loop doesn’t do what you probably expect it to do. A loop in your code will run through all of its iterations before the code continues. And that code that is on halt includes everything. Most importantly: The render loop. While your loop is running, Unity doesn’t do anything else, not even re-render your scene. This means that before the loop, you have one color, then the loop changes to another color, and then the image gets updated. So the player doesn’t even see the inbetween colors.

Don’t worry about performance at this point. The loop only takes a nanosecond or two. I’m not trying to tell you not to use loops or something :slight_smile:

The thing is that you are apprently trying to make a nice color change animation - but you need to let Unity render the image after each color change so the player actually sees the progression. One way to do this is to change by one step during each Update() call. But you have to only slightly change your code by using a coroutine instead. First off, add a using statement to the top if you don’t have it already:

using System.Collections;

Then, make your FadeOut method a coroutine by changing its return type to IEnumerator:

IEnumerator FadeOut() {

And finally, add yield return null; at the appropriate place. This statement, in this context, means that the code should be interrupted to be resumed at the next update. Or, for short: “Wait one frame”.

for(float i=0; i<1; i+=Time.deltaTime/lerpTime)
{
  myMat.SetColor(Color.Lerp(matColor, Color.clear, i));
  yield return null;
}

That should be all for this. As I mentioned, most of it is basic coding stuff that any beginner tutorial will cover, so have a look at them :wink:

Thank you so much for giving me such a detailed answer - you’re right, I’ve been stubborn and trying to run before I can walk.

I really appreciate your explanations rather than just pasting the code I need to fix it. I wish there was something like reddit gold I could give you. :stuck_out_tongue:

I’ll definitely start going through the tutorials you linked and get some basics down.