public static void UpdatePrefabInstancePropertyModifications(UnityEngine.Object prefabInstance, bool withUndo) { if (prefabInstance == null) { throw new ArgumentNullException("prefabInstance"); } if (!(prefabInstance is ISupportsPrefabSerialization)) { throw new ArgumentException("Type must implement ISupportsPrefabSerialization"); } if (!(prefabInstance is ISerializationCallbackReceiver)) { throw new ArgumentException("Type must implement ISerializationCallbackReceiver"); } if (!OdinPrefabSerializationEditorUtility.ObjectIsPrefabInstance(prefabInstance)) { throw new ArgumentException("Value must be a prefab instance"); } Action action = null; EditorApplication.HierarchyWindowItemCallback hierarchyCallback = (arg1, arg2) => action(); EditorApplication.ProjectWindowItemCallback projectCallback = (arg1, arg2) => action(); SceneView.OnSceneFunc sceneCallback = (arg) => action(); EditorApplication.hierarchyWindowItemOnGUI += hierarchyCallback; EditorApplication.projectWindowItemOnGUI += projectCallback; SceneView.onSceneGUIDelegate += sceneCallback; action = () => { EditorApplication.hierarchyWindowItemOnGUI -= hierarchyCallback; EditorApplication.projectWindowItemOnGUI -= projectCallback; SceneView.onSceneGUIDelegate -= sceneCallback; // Clear out pre-existing modifications, as they can actually mess this up { ISupportsPrefabSerialization supporter = (ISupportsPrefabSerialization)prefabInstance; if (supporter.SerializationData.PrefabModifications != null) { supporter.SerializationData.PrefabModifications.Clear(); } if (supporter.SerializationData.PrefabModificationsReferencedUnityObjects != null) { supporter.SerializationData.PrefabModificationsReferencedUnityObjects.Clear(); } UnitySerializationUtility.PrefabModificationCache.CachePrefabModifications(prefabInstance, new List <PrefabModification>()); } try { if (prefabInstance == null) { // Ignore - the object has been destroyed since the method was invoked. return; } if (Event.current == null) { throw new InvalidOperationException("Delayed property modification delegate can only be called during the GUI event loop; Event.current must be accessible."); } try { PrefabUtility.RecordPrefabInstancePropertyModifications(prefabInstance); } catch (Exception ex) { Debug.LogError("Exception occurred while calling Unity's PrefabUtility.RecordPrefabInstancePropertyModifications:"); Debug.LogException(ex); } var tree = PropertyTree.Create(prefabInstance); tree.DrawMonoScriptObjectField = false; bool isRepaint = Event.current.type == EventType.Repaint; if (!isRepaint) { GUIHelper.PushEventType(EventType.Repaint); } InspectorUtilities.BeginDrawPropertyTree(tree, withUndo); foreach (var property in tree.EnumerateTree(true)) { if (property.ValueEntry == null) { continue; } if (!property.SupportsPrefabModifications) { continue; } property.Update(true); if (!(property.ChildResolver is IKeyValueMapResolver)) { continue; } if (property.ValueEntry.DictionaryChangedFromPrefab) { tree.PrefabModificationHandler.RegisterPrefabDictionaryDeltaModification(property, 0); } else { var prefabProperty = tree.PrefabModificationHandler.PrefabPropertyTree.GetPropertyAtPath(property.Path); if (prefabProperty == null) { continue; } if (prefabProperty.ValueEntry == null) { continue; } if (!property.SupportsPrefabModifications) { continue; } if (!(property.ChildResolver is IKeyValueMapResolver)) { continue; } tree.PrefabModificationHandler.RegisterPrefabDictionaryDeltaModification(property, 0); } } InspectorUtilities.EndDrawPropertyTree(tree); if (!isRepaint) { GUIHelper.PopEventType(); } ISerializationCallbackReceiver receiver = (ISerializationCallbackReceiver)prefabInstance; receiver.OnBeforeSerialize(); receiver.OnAfterDeserialize(); } catch (Exception ex) { Debug.LogException(ex); } }; foreach (SceneView scene in SceneView.sceneViews) { scene.Repaint(); } }
public static void InternalOnInspectorGUI(UnityEngine.Object obj) { if (!EditorOnlyModeConfigUtility.IsSerializationEnabled) { GUILayout.Space(10); var color = GUI.color; GUI.color = new Color(0.8f, 0.1f, 0.4f, 1f); UnityEditor.EditorGUILayout.HelpBox( EditorOnlyModeConfigUtility.SERIALIZATION_DISABLED_ERROR_TEXT, UnityEditor.MessageType.Error); GUI.color = color; } if (!GlobalSerializationConfig.Instance.HideSerializationCautionaryMessage && !obj.GetType().FullName.StartsWith("Sirenix.OdinInspector.")) { GUILayout.Space(10); UnityEditor.EditorGUILayout.HelpBox( GlobalSerializationConfig.ODIN_SERIALIZATION_CAUTIONARY_WARNING_TEXT + "\n\n\n\n", UnityEditor.MessageType.Warning); var rect = GUILayoutUtility.GetLastRect(); rect.xMin += 34; rect.yMax -= 10; rect.xMax -= 10; rect.yMin = rect.yMax - 25; if (GUI.Button(rect, GlobalSerializationConfig.ODIN_SERIALIZATION_CAUTIONARY_WARNING_BUTTON_TEXT)) { GlobalSerializationConfig.Instance.HideSerializationCautionaryMessage = true; UnityEditor.EditorUtility.SetDirty(GlobalSerializationConfig.Instance); UnityEditor.HandleUtility.Repaint(); } GUILayout.Space(10); } if (!GlobalSerializationConfig.Instance.HidePrefabCautionaryMessage && obj is Component && OdinPrefabSerializationEditorUtility.HasNewPrefabWorkflow && (OdinPrefabSerializationEditorUtility.ObjectIsPrefabInstance(obj) || UnityEditor.AssetDatabase.Contains(obj)) && !obj.GetType().FullName.StartsWith("Sirenix.OdinInspector.")) { GUILayout.Space(10); UnityEditor.EditorGUILayout.HelpBox( GlobalSerializationConfig.ODIN_PREFAB_CAUTIONARY_WARNING_TEXT + "\n\n\n\n", UnityEditor.MessageType.Error); var rect = GUILayoutUtility.GetLastRect(); rect.xMin += 34; rect.yMax -= 10; rect.xMax -= 10; rect.yMin = rect.yMax - 25; if (GUI.Button(rect, GlobalSerializationConfig.ODIN_PREFAB_CAUTIONARY_WARNING_BUTTON_TEXT)) { GlobalSerializationConfig.Instance.HidePrefabCautionaryMessage = true; UnityEditor.EditorUtility.SetDirty(GlobalSerializationConfig.Instance); UnityEditor.HandleUtility.Repaint(); } GUILayout.Space(10); } }