Hello resident shader and coding experts,
I looked up Materials Property Blocks recently as a solution to reduce the load on my mobile device from instancing a bunch of the same shaders using the simpler GetComponent.material.SetInt() method. However, I’m having trouble getting the script to assign the Properties block correctly at run time.
I have the following shader with the properties listed below:
Properties
{
_Color(“Color”, Color) = (1,1,1,1)
_MainTex(“Albedo (RGB)”, 2D) = “white” {}
_NormalMap(“Normal map”, 2D) = “normal” {}
_Glossiness(“Smoothness”, Range(0,1)) = 0.5
_Metallic(“Metallic”, Range(0,1)) = 0.0
_GlowStrength(“Glow Strength”, range(0,1)) = 1
[HDR] _Emission(“Emission”, color) = (0,0,0)
[Toggle] _CenterGlow(“Glow from Center”, float) = 0
[PerRendererData] _StencilMask(“Stencil Mask”, Int) = 0
}
The property I’m trying to change per object is the _StencilMask. I have 3 copies of the same mesh, each with 6 parts. Each corresponding part has the same material, for a total of 6 materials. But they all use the same shader. I could use a single material for all of them, but since some of them has normal maps I’d rather not do it through code.
I have the following script to assign the _StencilMask integer (#1-3) at run time to each set of objects:
public class SetStencil : MonoBehaviour
{
public GameObject[ ] p1Stuff = new GameObject[5], p2Stuff = new GameObject[5], p3Stuff = new GameObject[5];
private MaterialPropertyBlock mask1, mask2, mask3;
void Awake() //sets up property renderer compponents for property blocks.
{
mask1 = new MaterialPropertyBlock();
mask2 = new MaterialPropertyBlock();
mask3 = new MaterialPropertyBlock();
mask1.SetInt(“_StencilMask”, 1);
mask2.SetInt(“_StencilMask”, 2);
mask3.SetInt(“_StencilMask”, 3);
}
private void AssignMask(GameObject[ ] _obj, MaterialPropertyBlock _mask)
{
for (int i = 0; i < 5; i++)
{
_obj.GetComponent().SetPropertyBlock(_mask);
Debug.Log(_obj.GetComponent().HasPropertyBlock());
}
}
private void Start()
{
AssignMask(p1Stuff, mask1);
AssignMask(p2Stuff, mask2);
AssignMask(p3Stuff, mask3);
//Debug.Log(“mask 1 is " + mask1.GetInt(”_StencilMask")); //These are correct
//Debug.Log(“mask 2 is " + mask2.GetInt(”_StencilMask"));
//Debug.Log(“mask 3 is " + mask3.GetInt(”_StencilMask"));
//Debug.Log(“artery 1 mask is " + p1Stuff[0].GetComponent().material.GetInt(”_StencilMask")); //These are incorrect.
//Debug.Log(“artery 2 mask is " + p2Stuff[0].GetComponent().material.GetInt(”_StencilMask"));
//Debug.Log(“artery 3 mask is " + p3Stuff[0].GetComponent().material.GetInt(”_StencilMask"));
}
}
All the objects are assigned correctly in editor, but for some reason, the AssignMask() functions are either being ignored or is not assigning the values correctly, and I can’t seem to figure out why. The materials property blocks are being assigned correctly, as shown by the debug logs below, but they aren’t being transferred to the material.
If the script was working, p1Stuff[0], p2Stuff[0], and p3Stuff[0], should have the _StencilMask values of 1,2 and 3, respectively. They are all currently 0 (default), so the _StencilMask is not being assigned.
I’m at a loss as to what I’m doing wrong. It might be something so obvious that i’m overlooking. Any help in the matter would be much appreciated.
Thanks in advance. ![]()