Changing color based on ground color

Hello everybody,

I’m trying to change the color of my object based on the color/material of the object that it’s on.

I was just going to do this using the material’s name. For example, I have 2 materials, one is “Ground” and one is “RedGround”. I called both the object material and the physics material this.

Using the OnCollisionEnter event, I wanted to set the object’s color. Here’s what I tried:

function OnCollisionEnter(collision : Collision) {
	var mat = collision.collider.material;

	print(mat.name);
	
	if(mat.name == "RedGround"){
		renderer.material.color = Color.red;
	}
	else{
		renderer.material.color = Color.white;
	}
}

For some reason, even when I’m on the “RedGround” material, the mat.name==“RedGround” expression NEVER evaluates to true. When I do Debug.Log(mat.name), I get “RedGround (Instance)” in the unity console. The Unity reference states that name is a String… is this not the case?

Should I be using materials to determine what kind of ground my character is on? Is there a better way to handle it?

Also, my object has the Self-Illumination/Defuse shader on it. Is there a way to only change the color of the part that is the illumination part of the texture? Currently, it changes the entire color, but parts of my object are gray, which turns into a redish-gray when changed.

Thanks!

-Sam

Anyone?

I’m not sure I follow your question. You said that the conditional ‘mat.name == “RedGround”’ is never evaluating to true, but you also said the name that’s displayed is ‘RedGround (Instance)’. So why would you expect the conditional to evaluate to true in that case? (Or am I just not understanding the question?)

I want to know if my character is on top of the material “RedGround”

mat.name should be a String that’s equal to “RedGround” (unless .name isn’t actually a String, but the documentation says it is)

So… is the (Instance) part indicating that it’s NOT a string? What exactly is it? How can I identify the material that my character is on and do something in response to that?

If Debug.Log prints “RedGround (Instance)”, then that’s what the name is.

–Eric

I guess I thought that Unity was appending some sort of datatype to the output of the string, and that the (Instance) part wasn’t part of the actual string.

Why does Unity append the (Instance) to my material name? The material name itself is (RedGround), but every instance of the redground material gets the added (Instance) appended? That seems… silly.

Is there a different way to detect what kind of ground that I’m on?

It’s just a convention, I think. (In some cases it’s useful to know whether an object has been cloned or otherwise created dynamically.)

As with most things, there are many ways. For example:

  • You could stick with the name-based method, but use string manipulation to remove parts of the name that aren’t of interest (some might mention though that lots of string manipulation can end up giving the GC more work to do).

  • If you don’t need tags for anything else, you could use tags for this.

  • You could create a simple component type that has an enum representing the surface type, and then query that component to see what the type of the surface is.

  • You could create a custom component type that stores an ID for the material (e.g. a string or enum), a render material, and a physics material as a ‘package’ that groups all that data together. Objects that have a material type can then have another custom component that references one of these ‘material’ objects (essentially an application of the flyweight pattern). When you collide with a collider, you’d then grab the ‘material reference’ component and grab the ‘material’ reference from that component, and then you can acquire any info about the material that you might need. (This approach might be overly complex for some cases, but for for others it might be suitable. FWIW, I’ve used this method to identify the properties of a surface that a game object is in contact with, and it works fine.)

Ah, that makes a lot of sense. If tags are easy, I’ll probably do that.

Essentially, I’ll be granting the player different abilities that they can activate while on certain types of ground.

Also, for changing colors… I have the “Defuse w Illum” type material set on my character. Parts of the character are gray, while other parts are white. If I just set the color of the object to Color.Red, the gray part gets reddish as well. I want only the white parts to become red. Is there an easy way to do this?

On another side note… how do you map UV coordinates in Unity? Unity seemed to import my UV coordinates from Blender fine, but is there no internal way to map textures within Unity?