Search Unity

Resolved MaterialPropertyBlock Settings not working in Build?

Discussion in 'General Graphics' started by BTStone, Aug 6, 2020.

  1. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Hey there,

    using Unity 2019.4.1f1
    using URP 7.4.1

    I created a shader using ShaderGraph where I can blend a texture onto the maintexture, in my case the Sprite used by the SpriteRenderer.

    Now I also wrote a MonoBehaviour which is basically a conveniance script for my artist, who will attach this script to any sprite and will get a bunch of settings to adjust.
    The texture to blend, tiling, offset, colors etc.

    In this script I use OnValidate() to overwrite the MaterialPropertyBlock so only the material of the very selected GameObjects gets changed. And this works perfectly. In Edittime and in playmode, everythings looks as expected and gets changed the moment the settings are touched. Great.

    Only problem: When I build the game and the scene loads I only see the basic sprites, without the "saved" changes. I found a workaround by using OnEnable() and calling the responsible logic for the adjustments, and that does indeed work.

    It feels like the build process resets the material and when the game runs we have to manually "change" the materialpropertyblock with the serialized settings once again. Is this true?
    The MaterialPropertyBlock doesn't get serialized? Which at least feels weird, since the changes are still present when I switch scenes in the Editor or even restart the Editor.
    Or is this a bug?
     
    BrandyStarbrite likes this.
  2. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Bump. Any insight on this?
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It's probably possible to serialized a material property block, it is a c# class, though most of the important stuff is hidden in c++. But the material property block assigned to the renderer is not serialized. Your
    OnValidate()
    is presumably re-applying the material property block as soon as it loads in the editor, but that function doesn't run in standalone, so is only going to work in the editor. You need to assign the material property block on
    Start()
    or maybe
    OnEnable()
    to ensure your saved changes are seen at runtime.

    In short, you need to create, set, and apply a material property block from a separate serialized list of properties
    OnEnable()
    .
     
    BTStone likes this.
  4. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Thanks for your reply. Yes, as mentioned in the OP I got it working using OnEnable, I just wanted to know the behind the scenes stuff and how the MaterialPropertyBlock works when manipulating it directly. I checked the scene file and there was no indication that anything related to the material itself was changed or adjusted, just my serialized values, so it definitely does not get serialized in my case. Thanks for the clarification, highly appreciated :)