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();
            }
        }
예제 #2
0
        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);
            }
        }