Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    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. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Don't miss out on the Unite LA Keynote for the latest information from Unity! Set a reminder!
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    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:
    214
    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:
    214
    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.