- Home /
Change material rendering mode in runtime
Hi, I'm trying to change the rendering mode of material to transparent when my player is near the object. Here is what I got so far.
using UnityEngine;
using System.Collections;
public class ChangeAlpha : MonoBehaviour
{
public Renderer targetObject;
public float alpha = 0.25f;
Color newColor;
void Awake ()
{
targetObject = targetObject.GetComponent<Renderer> ();
}
void OnTriggerStay (Collider other)
{
if (other.gameObject.tag == "Player")
{
newColor = targetObject.material.color;
targetObject.material.SetFloat("_Mode", 3f);
newColor.a = alpha;
targetObject.material.color = newColor;
}
}
void OnTriggerExit (Collider other)
{
if (other.gameObject.tag == "Player")
{
newColor.a = 1f;
targetObject.material.SetFloat("_Mode", 0f);
targetObject.material.color = newColor;
}
}
}
This code is not working, but when I change the material rendering mode to transparent before run time and remove the material.setfloat, it was working. but I want the material to be opaque when not trigger. So how can I do this?
Answer by bellicapax · Nov 02, 2016 at 05:44 PM
I'm sorry to necro this answer, but I just wanted to clarify in case anyone else came across this question.
This answer assumes that you are using the Unity Standard shader.
If you compile and view the Standard shader code, you can see at the very end that it uses a CustomEditor of type "StandardShaderGUI"
If you peek at that code (which others have done), you'll see that it does more than just change the "_Mode" of the shader.
Here is a helper class that can perform the actions of the StandardShaderGUI at runtime assuming the Material you pass in is using the Unity Standard shader:
using UnityEngine;
public static class StandardShaderUtils
{
public enum BlendMode
{
Opaque,
Cutout,
Fade,
Transparent
}
public static void ChangeRenderMode(Material standardShaderMaterial, BlendMode blendMode)
{
switch (blendMode)
{
case BlendMode.Opaque:
standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
standardShaderMaterial.SetInt("_ZWrite", 1);
standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
standardShaderMaterial.renderQueue = -1;
break;
case BlendMode.Cutout:
standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
standardShaderMaterial.SetInt("_ZWrite", 1);
standardShaderMaterial.EnableKeyword("_ALPHATEST_ON");
standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
standardShaderMaterial.renderQueue = 2450;
break;
case BlendMode.Fade:
standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
standardShaderMaterial.SetInt("_ZWrite", 0);
standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
standardShaderMaterial.EnableKeyword("_ALPHABLEND_ON");
standardShaderMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
standardShaderMaterial.renderQueue = 3000;
break;
case BlendMode.Transparent:
standardShaderMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
standardShaderMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
standardShaderMaterial.SetInt("_ZWrite", 0);
standardShaderMaterial.DisableKeyword("_ALPHATEST_ON");
standardShaderMaterial.DisableKeyword("_ALPHABLEND_ON");
standardShaderMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON");
standardShaderMaterial.renderQueue = 3000;
break;
}
}
}
The other important thing to note is that while this will always work in the Editor, you will want to make sure that you have a shader variant that uses the blendmode you want referenced somewhere so that when you build, it will work. You can see if Unity has automatically grabbed the shader variant you need by going to Project Settings->Graphics and at the bottom under Shader Preloading click "Save to asset". You need a variant under Standard that has _ALPHAPREMULTIPLY_ON defined for the "Transparent" mode to work (which you can see from the above script) as well as all the other defines that the shader is using.
If you don't see a variant you need listed, you can run your program, make all the changes to the shader, and click this button to save a new ShaderVariantCollection as it tracks variants at runtime. You can then add this collection the the Preloaded Shaders array and it should be added to the build as far as I can tell (haven't tested currently).
I'd give you more upvotes, but alas I can only do it once. /bow thanks a lot for this.
I had issues with this until I added standardShader$$anonymous$$aterial.SetFloat("_$$anonymous$$ode", 2);
Great answer! To complete this, you would also want to set e.g. standardShader$$anonymous$$aterial.SetOverrideTag("RenderType", "Fade"), and possibly the _$$anonymous$$ode too, as some other modules -- including Unity's new native PostProcessing2 -- sometimes test against these, leading to unwanted results if not also changed.
I use standardShader$$anonymous$$aterial.SetInt("_SrcBlend", int)UnityEngine.Rendering.Blend$$anonymous$$ode.SrcAlpha)
(as opposed to Blend$$anonymous$$ode.One) for the Transparent blend-mode.
Like the other comments said, you need to add the following
material.SetFloat("_Mode", X); where X -> 0 opaque, 1 Cutout, 2 Fade, 3 Transparent
If you don't set this, then the unity editor will reset it back to opaque when you look at it in the inspector
Answer by chris3331 · Dec 21, 2015 at 04:38 PM
I guess you are missing the keywords to activate the rendering mode! Have a look here:
http://answers.unity3d.com/questions/1016155/standard-material-shader-ignoring-setfloat-propert.html
and here...
http://docs.unity3d.com/Manual/MaterialsAccessingViaScript.html
Hope that helps!!
Where do you put/access/use the keywords? I've been desperately searching for days with no luck, and every answer just points to that documentation which I can't seem to get to work.