I'm using Unity 5.5.1f1 and I'm running into a really bad bug that prevents you from making prefabs out of MaterialUI components.

When MaterialUI components are turned into prefabs some sort of instability/bug occurs that prevents you from editing any values on the prefab instance in the scene. Trying to enable/disable the prefab or any of its children in the inspector has no effect. The active state of any game object will always remain whatever state it was when the prefab was created. Editing any inspector values will be of no use as they will automatically reset back to their prefab values immediately.

This also leads to instability in the editor where it prevents you from renaming any instance in the scene, including instances that are not prefabs. Clicking an object to rename it or using the right-click context menu Rename command do nothing. This seems like a pretty bad instability that is affecting the unity Editor itself in unexpected ways.

To reproduce the bug.

Start a new Unity project.

Import MaterialUI

In a new scene, create a UI/Canvas

On the newly created Canvas add MaterialUI/MaterialUIScaler script

On the Canvas add MateriulUI/VectorImage

Turn the Canvas game object into a prefab.

Once you have followed these steps try interacting with the prefab in the inspector. You will not be able to change any values. Also try renaming any game object in the scene - it will not work.

I've narrowed the bug down to some sort of interaction between VectorImage, MaterialUIScaler, and turning it into a prefab. Those are the minimum components needed to cause this issue. If you do not have a VectorImage or do not have a MaterialUIScaler on the Canvas, you do not see this issue when creating a prefab.

This is pretty lame as it prevents the ability to create MaterialUI prefabs; that's a pretty big deal. Now I have to maintain separate copies of my MaterialUI designs in each scene that contains the same UI.

I've narrowed this down further. It seems the offending call is VectorImage.cs line 353:

EditorUtility.SetDirty(this);

This line doesn't offend when the UI components are not inside of a prefab, but this breaks the UI/Editor when this code appears from within a prefab.

Furthermore I've narrowed it down to the fact that in all of your components you are initializing the EditorUtility.cs class and attaching your editor update delegate in the public constructors of your components:

Unity recommends never using the constructors of Unity components like MonoBehaviours, etc. because of the way Unity handles serialization. You are making extensive use of constructors for initialization purposes:

MonoBehaviour constructors are called before the game/editor is necessarily ready. That's why you must call initialization in Awake() instead. When used in prefabs combined with how Unity does serialization/deserialization some kind of instability is occurring with the way the delegates are getting hooked up in conjunction with the EditorUtility.SetDirty() call from within the constructors.

You might want to say this is a bug in Unity, but clearly they've told us never to use constructors for initialization and to always use Awake() and Start().

By looking at the MaterialUI scripts though it's quite clear that a lot of the UI components are initializing things in their constructors.

Please refactor all of your constructor initialization code to use the override of Awake() instead and release a patch update for MaterialUI. This is the correct Unity best practice and it will allow prefabs of MaterialUI components to be created.

Just so you know I love MaterialUI, it's probably one of the best Unity UI packages out-of-the-box. I have experienced some bad corruption/instability when using it, but I'm going to keep trying to work with it. If you could fix this issue (and hey I've already debugged it for you!) that would be amazing.

Also, I've run into instability with MaterialUI where things will break, like the dialogs will stop working with calls to DialogManager.ShowAlert() - they just stop appearing. Or a button on the app bar that toggles the nav drawer will just stop working between plays in the Unity editor.

If I take my canvas that has the MaterialUI components on it, copy it, delete it from the scene, and then paste it from the clipboard things will work again for a while. And then they will stop and I will have to repeat the process of copy, delete, paste. It's maddening.

I wouldn't doubt it if weird instability like this was also being caused by the use of initialization in constructors.

Your comment on this question:

Your name to display (optional):

Email me at this address if a comment is added after mine:Email me if a comment is added after mine

Privacy: Your email address will only be used for sending these notifications.

Your answer

Your name to display (optional):

Email me at this address if my answer is selected or commented on:Email me if my answer is selected or commented on

Privacy: Your email address will only be used for sending these notifications.

Thanks very much for bringing this to my attention, it looks to be a bit of an oversight on my part while I was trying to make everything work as well in the editor as in play mode.

I'm not 100% certain, but I believe the reason I avoided using Awake for some of those classes was because it isn't called when scripts are recompiled (eg. when you change+save a script and go back to the editor), and I needed a way to initialize some things regardless of whether it was starting play mode, edit mode, or just a recompilation/deserialization.

I'm a tad busy right now, but I'll definitely look into fixing this as soon as I can. Thanks again for the help :)

~ Declan.

Your comment on this answer:

Your name to display (optional):

Email me at this address if a comment is added after mine:Email me if a comment is added after mine

Privacy: Your email address will only be used for sending these notifications.

I've just finished modifying the behaviour of some of the components so they don't need EditorUpdate at all, thus removing the need for anything to happen in the constructor, which should solve the issues you've been experiencing. These changes will be present with the next update, which we will be pushing out as soon as we can.

Awesome! Thanks again for looking into this and making a new update for it. I was going to say that if you were utilizing the constructor for something specific (which it sounds like maybe you were, and is usually the case) then maybe Unity would have an official answer as to how to achieve what you needed without using the constructor (maybe they've run into the same use case before). But it sounds like you found a new resolution. Fantastic. I appreciate the effort on this.

Your comment on this answer:

Your name to display (optional):

Email me at this address if a comment is added after mine:Email me if a comment is added after mine

Privacy: Your email address will only be used for sending these notifications.