- Home /
CustomPropertyDrawer can't restrict multi editing
Hi There,
I want to disable multi object editing for any component which has a variable using my CustomPropertyDrawer. However I don't want to write a new custom editor for every single component that declares this variable type. Is this at all possible?
Alternatively, Unity seems to detect fields which differ in value by putting a hyphen in, '-'. Is there a way I can enable this functionality on my CustomPropertyDrawer?
Thanks in advance.
Answer by huulong · Oct 10, 2016 at 10:40 AM
Solution 1
Allow multi-edit on the custom property drawer (supports hyphen)
Custom property drawers support multi-editing as long as they only draw properties. If you are drawing with a line such as:
floatValue = EditorGUI.FloatField (position, floatValue);
then multi-edit won't be supported. Instead, the value will belong to the component of the last object selected ( property.serializedObject.targetObject
). It may be convenient in some situations, but also tricky what feels like a multi-edit is actually a single edit.
Instead, use:
EditorGUI.PropertyField (position, property.FindPropertyRelative ("floatValue"), new GUIContent ("My Float"));
There is exactly the same issue with custom inspectors if you allow multi-editing but override OnInspectorGUI
and use target
. Instead, you should use serializedObject.FindProperty()
.
Result below (Alert Box has a custom drawer):
Solution 2
During multi-editing, hide the custom PropertyDrawer and only that. Keep showing the other properties of the component.
In your custom PropertyDrawer class, check if property.serializedObject.isEditingMultipleObjects
is true. If so, return immediately so that nothing is drawn. This is possible because the serialized object contains information on both the property and the inspected components (stored in property.serializedObject.targetObjects
).
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
if (property.serializedObject.isEditingMultipleObjects)
return;
// usual drawing code here
// ...
}
Don't forget to shrink the height used by your drawer to 0 in multi-edit:
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
if (property.serializedObject.isEditingMultipleObjects)
return 0f;
// usual height calculation here
// ...
}
Result below:
References:
Custom Editor : Call a function on multiple selected objects
Custom property drawers support multi-editing as long as they only draw properties. ... the value will belong to the component of the last object selected
This is no longer true (Unity 5.6).
Using an IntField and an EditorGUILayout.Popup both support multi-editing in my PropertyDrawer:
attachpoint_field.intValue = EditorGUILayout.IntField(attachpoint_field.displayName, attachpoint_field.intValue);
attachpoint_field.intValue = EditorGUILayout.Popup(attachpoint_field.displayName, attachpoint_field.intValue, child_list.ToArray());
The IntField doesn't support hyphening on different values, but does apply the edited value to all selected objects.
The Popup both supports hyphening on different values and applies the edited value to all selected objects.
It's still not "supported". What you are describing is "not working as intended", because yes, the IntField and Popup will apply their values to all selected objects, but they always will do this even when they shouldn't. If you have multiple different values on objects and select them, all values will be overridden by one of the selected objects. Basically, this supports sharing values, but not having unique values at all, which we shouldn't use because it's against the Unity inspector paradigm.
Exactly. And this "support" is nothing new. The behaviour was like that since multi editing was implemented. Propertydrawers should always "support" multiediting at some level. If you can't use a PropertyField and you have / want to implement your own GUI you should either deactivate the propertydrawer, or in case of conflicting values don't draw your usual GUI but ins$$anonymous$$d present a button to "unify" all the different instances and once unified you can show your GUI.
A propertydrawer which "assumes" no multi editing is a bad implementation. Both solutions huulong presented are a viable solution. Though if you like an overwrite feature you should implement it in some way but still provide consistency. The worst thing is a GUI that suddenly breaks various settings just because you selected multiple objects at once.
Note that the important property of a SerializeProperty is has$$anonymous$$ultipleDifferentValues. If you ignore that and just read and write the value you get from any of the "value" properties you will unintentionally overwrite the values of the instances.
Cheers, this is a lifesaver! I was using a rather complex custom property drawer to compact a bunch of settings into an int, but selecting multiple object would set them all to whatever value I had on the last selected (clearly not what I wanted). The return on multiple selected saved my ass on that one. Thanks!
Your answer
Follow this Question
Related Questions
Unity Tabs is Empty or Broken someTimes 0 Answers
EditorGUI add SortingLayer-like list to custom Editor 1 Answer
Why Unity correctly builds a project but the editor freezes on the Build Progress window? 2 Answers
How do I repaint/refresh/focus without calling Key Events multiple times? 1 Answer
Multiple editor windows combined 0 Answers