Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Unity UI Masked Material Shader Changes not working correctly

Discussion in 'Unity UI & TextMesh Pro' started by Piflik, Mar 13, 2018.

  1. Piflik

    Piflik

    Joined:
    Sep 11, 2011
    Posts:
    215
    I regularly run into the same problem currently:

    I have a Material on an UI-Image that is masked by a parent with a Mask Component. Now I want to change some Material Properties via script (SetTexture, SetFloat, etc). I know that there is a new-ish 'MaterialForRendering' property, especially for masked Materials, but for some reason, Unity is unable to use this properly. When I edit properties before turning the Mask on, they are not applied to the masked material, and vice versa. (When I enable the Mask for the first time, the material is copied correctly, but on all subsequent enable/disables, the materials seem to be handled completely separate.)

    I already filed a bug report weeks ago (994413), but it was closed because apparently it is "its not the common case" to want to enable/disable a Mask after changing material properties during runtime.

    An additional problem is that we create all our UI via code, not buy building it in the Editor, so even if I never enable/disable a Mask, I cannot guarantee that material changes happen always after Unity has copied the Material for masking. I can do the changes after parenting, but the masking/material-copying seems to happen sometime during rendering, so I have to make some changes to the 'material', but later ones to the 'materialForRendering'.

    My current 'workaround' is to never disable/enable masks (which brings some limitations to how my application looks) and duplicate every change manually like so (which is stupid):


    img.material.SetFloat("Name", value);
    img.materialForRendering.SetFloat("Name", value);


    Is there a known fix that actually works, or is my use-case just too outlandish?
     
  2. Piflik

    Piflik

    Joined:
    Sep 11, 2011
    Posts:
    215
    I just now found a possible solution.

    I noticed that the masked material will be updated corerctly when I disable the object and enable it again. So I got the UI Repository from Bitbucket and had a look at MaskableGraphic.cs. I copied the following two lines from OnDisable() to RecalculateMasking(), compiled the solution into a dll and replaced the one in my unity installation:

    Code (CSharp):
    1. StencilMaterial.Remove(m_MaskMaterial);
    2. m_MaskMaterial = null;
    I do not know if that produces problems elsewhere, though.