- Home /
[C#] Checking InstanceOf?
When running my Debug.Log tests, I get the following output. n is a GameObject variable, and landingHexMat is a Material variable.
n.GetComponent<MeshRenderer>().material == marker_hex_green (Instance) (UnityEngine.Material)
landingHexMat == marker_hex_green (UnityEngine.Material)
I want (n.GetComponent().material == landingHexMat) to return TRUE, but it returns false. What do I need to change???
With the pseudo-code here and lack of context, it is difficult pinpoint your problem. Note that if you make any change to your materials, your original materials will be replaced by new material instances. This will invalidate any comparison to the original material.
how can I compare and see if the material on a gameobject is an instance of the material referenced by the variable? $$anonymous$$y problem is the "(Instance)" part
Have you tried .shared$$anonymous$$aterial ins$$anonymous$$d of .material?
just tried this, but got the exact same results. said marker_hex_green (Instance) rather than just marker_hex_green. Same for if I use material.name or .toString() (and same with shared$$anonymous$$aterial)
Is there no instanceof or something?
EDIT: Turns out I'm supposed to use .equals ins$$anonymous$$d of ==, but the comparison still does not return true.. Right now the only way to get it to return true is if I compare the rgb (not alpha) color properties, but SURELY theres a better way than this...
Answer by rutter · Jun 05, 2014 at 08:02 PM
You could query the instance ID of the sharedMaterial
property:
bool match = originalMat.GetInstanceID() == renderer.sharedMaterial.GetInstanceID()
That assumes you're looking for a common instance.
You could also write an extension method which checks the shader and parameters used by each material. If the shaders and parameters match, it stands to reason that the materials are equivalent.
The instanceID's are not the same, just tested with debug.log. What exactly do you mean by checking the shaders and parameters? What parameters exactly?
If the instanceID's aren't the same, they're not the same object. The equality check is firm and unyielding.
It's important to distinguish between reference equality (these two references point to exactly the same memory location) and value equality (these two references point to objects which are functionally identical).
What I mean by checking the shaders and parameters: your material, like any object, has some data associated with it. This tends to include a shader (the program which runs the material) and some parameters (like color, textures, and so on).
If two materials use the same shaders with the same parameters, they're functionally equivalent. If they don't, they're not.
Answer by Bunny83 · Jun 05, 2014 at 10:09 PM
Are you sure that they are actually the same? Keep in mind when ever you access ".material" you will create an instance / copy of the original material. To aviod this you always have to access sharedMaterial.
Just to make that clear, even if you access .material just one time, Unity will create a seperate instance for this renderer which will be used from now on.
Also keep in mind that if you change something on the sharedMaterial, every instance that uses the shared material will be affected as well.
Read the .material page carefully. It's explained there.
Did not know that, thanks! But yes I'm sure they're actually the same because I have another function that does:
n.GetComponent<$$anonymous$$eshRenderer>().material = landingHex$$anonymous$$at;
That won't work. Whenever you access (read or write) .material, Unity will create a copy of the material.
You have to use
n.GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial = landingHex$$anonymous$$at;
When you want to check the material you have to use shared$$anonymous$$aterial as well:
if(n.GetComponent<$$anonymous$$eshRenderer>().shared$$anonymous$$aterial == landingHex$$anonymous$$at)
{
//...
Just tried that and it still is not returning True..
Heres my full code for reference. I only have 4 materials that the hexes should be, so I should NEVER receive the error message, which I am, since the boolean checks dont return true.
Are you sure you don't use .material anywhere in your code? $$anonymous$$aybe from another script? I did something similar in the past and it worked as expected. The only reasons why you might get an material instance are:
you accessed .material or .materials somewhere.
you modified a material property in the inspector of one of your tiles which might also create an instance.
just double checked, and I did not access .material anywhere else or in any other script. The only use of "material" was when declaring the $$anonymous$$aterial variables, and in the two functions i screenshot(ted?).. The game does make them flash by lowering and raising the alpha level when moused over, but wouldnt it still be considered the same material?
Your answer
Follow this Question
Related Questions
Changing one material instance affects all instances? 4 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers