- Home /
How do I make fields in the inspector go bold when prefab value is overridden
How do I get custom inspectors to bold their fields when the target has an overridden value from its prefab.
This is the standard functionality of the default inspector and I want to replicate this for my own inspectors. Is there an easy way to do this?
I really really need to know the answer to this question.
Has any one found any answers out there!?
Answer by Bunny83 · Feb 10, 2012 at 01:35 PM
This information can only be retrived from a SerializedProperty. The default inspector uses a PropertyField for every field. Inside PropertyField you can find this code which sets the bold state for this property according to the "prefabOverride" value of the serialized property:
[...]
bool isInstantiatedPrefab = property.isInstantiatedPrefab;
if (isInstantiatedPrefab)
{
EditorGUIUtility.SetBoldDefaultFont(property.prefabOverride);
}
[...]
If you need to develop some advanced editor GUI stuff, i recommend to use ILSpy on the UnityEditor.dll (and UnityEngine.dll) to see how the GUI functions are implemented.
This is so awesome! It's so enormously much easier to work when you know what your code does. Thank you so much.
@Bunny83: thank you very much. ILSpy is saving my life!!!
@Bunny83 any idea how Unity's SerializedProperty detect that there's been a change in a nested property (say field in a struct or an array element)? Do they use a Diff system in C++ land? - I'm trying to emulate this certain behaviour of font turning bold on members with different values than the prefab in my framework. I use my own field/property wrapper so SerializedProperty is pretty much useless to me. I got it to work in a basic way by comparing the serialization data of the instance and the prefab, but it's a bit more tricky to make it work with sequences, dictionaries and for members in objects. I wonder how would you go about implementing it :p.
[Edit] I just remembered PrefabUtility.GetProperty$$anonymous$$odifications
which I 'hope' would be able to detect changes even if the field/property wasn't serializable by Unity (dictionary etc) - This should give me some information about what changed, bringing me closer to the solution...
[Edit] forget about last Edit lol. Still interested in your opinion ;p
@vexe: Well, i have no idea how they explicitly have implemented that. Since a SerializedProperty knows to which SerializedObject it belongs and the SerializedObject knows that it's a prefab instance, they might simply get the prefab as reference and see if the value is different.
They probably cache that information along with the SerializedProperty. It's only updated (maybe wwith the mentioned procedure) when the object has been marked as dirty. It seems (just reading steinbitglis answer below ^^) that Unity doesn't even store / serialize changes when you don't mark the object as dirty. So it's a bit of a hand-in-hand process of the serialization system and the editor GUI i guess.
$$anonymous$$ight be worth updating answer to mention EditorGUI.BeginProperty since that wrapper will allow all the bells and whistles of a normal property field. Also worth mentioning EditorGUILayout.GetControlRect as a way to get it to auto-layout (since there's no EditorGUILayout version of BeginProperty).
Answer by steinbitglis · Feb 10, 2012 at 10:27 AM
If you mark your object after altering it with EditorUtility.SetDirty(arg), it will be stored properly. We had the same problem in our project, causing custom components to replace their values with prefab values at random.
I don't know yet, how to know that the value should be bold, so the change is not visible in my custom component editor, but in the debug editor, the value is written with a bold font.
Tried this out, and undo works regularly, but I still have the values being replaced issue. Did you find something else about this bug (because I suppose it's a bug)? Thanks :)
$$anonymous$$aybe you've renamed the field or something? There's lots of situations that could cause this.
Oops, didn't mention the problem was relative to prefab instances, sorry. Actually I found that the problem is due to sliders: when you change them, other than setting the undo state, you also have to call PrefabUtility.RecordPrefabInstanceProperty$$anonymous$$odifications after the value has fully changed, otherwise it gets recorded at the wrong point.
Nice tip it worked prety well, i'm getting some kind of $$anonymous$$onoBehaviour invalid operation before this. The weird part is one of my prefabs are working without EditorUtility.SetDirty(arg) maybe because i have olny one instace of then in the scene.
Since this is still prevalent on Google I should mention that as of 5.3+ Unity recommends using Undo.RecordObject ins$$anonymous$$d of EditorUtility.SetDirty for in-scene objects.
Answer by jedy · Nov 26, 2012 at 01:48 AM
Here is a little code snippet that calls EditorGUIUtility.SetBoldDefaultFont :
private MethodInfo boldFontMethodInfo = null;
private void SetBoldDefaultFont(bool value) {
if(boldFontMethodInfo == null)
boldFontMethodInfo = typeof(EditorGUIUtility).GetMethod("SetBoldDefaultFont", BindingFlags.Static | BindingFlags.NonPublic);
boldFontMethodInfo.Invoke(null, new[] { value as object });
}
}
You can easily use this to bold stuff if the prefab has changed.
//Example with a SerializedProperty property
if(property.isInstantiatedPrefab)
SetBoldDefaultFont(property.prefabOverride);
Thanks Bunny83 for heading me into the right direction.
Answer by turbanov · Jan 13, 2016 at 07:27 PM
If someone wants to make a custom "boldable-on-override" property drawer (as I do), he can place his GUI code between BeginProperty/EndProperty pair. This way you will also get the standart "Revert Value to Prefab" menu when right-clicking.
EditorGUI.BeginProperty(position, label, property);
/// Your GUI code here...
EditorGUI.EndProperty();
Exactly what I was looking for, thanks! Also worth mentioning EditorGUILayout.GetControlRect as a way to get it to auto-layout (since there's no EditorGUILayout version of BeginProperty). Bonus: script reference for EditorGUI.BeginProperty, for easy access :)
Your answer
Follow this Question
Related Questions
Automatically increment an integer field in a bunch of prefab gameobjects in the unity editor. 0 Answers
Custom editor window does not show prefab overrides 2 Answers
Script for Revert Value to Prefab 1 Answer
Unable To Override A Prefab 2 Answers
Custom editor values set in prefab editor not set in prefab asset 0 Answers