internal static void DisplayObjectContextMenu(Rect position, Object[] context, int contextUserData) { // Don't show context menu if we're inside the side-by-side diff comparison. if (EditorGUIUtility.comparisonViewMode != EditorGUIUtility.ComparisonViewMode.None) { return; } Vector2 temp = GUIUtility.GUIToScreenPoint(new Vector2(position.x, position.y)); position.x = temp.x; position.y = temp.y; GenericMenu pm = new GenericMenu(); if (context != null && context.Length == 1 && context[0] is Component) { Object targetObject = context[0]; Component targetComponent = (Component)targetObject; // Do nothing if component is not on a prefab instance. if (PrefabUtility.GetCorrespondingConnectedObjectFromSource(targetComponent.gameObject) == null) { } // Handle added component. else if (PrefabUtility.GetCorrespondingObjectFromSource(targetObject) == null && targetComponent != null) { GameObject instanceGo = targetComponent.gameObject; PrefabUtility.HandleApplyRevertMenuItems( "Added Component", instanceGo, (menuItemContent, sourceGo, _) => { TargetChoiceHandler.ObjectInstanceAndSourcePathInfo info = new TargetChoiceHandler.ObjectInstanceAndSourcePathInfo(); info.instanceObject = targetComponent; info.assetPath = AssetDatabase.GetAssetPath(sourceGo); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceGo); if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(instanceGo)) { pm.AddDisabledItem(menuItemContent); } else { pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabAddedComponent, info); } }, (menuItemContent) => { pm.AddItem(menuItemContent, false, TargetChoiceHandler.RevertPrefabAddedComponent, targetComponent); } ); } else { bool hasPrefabOverride = false; using (var so = new SerializedObject(targetObject)) { SerializedProperty property = so.GetIterator(); while (property.Next(property.hasChildren)) { if (property.isInstantiatedPrefab && property.prefabOverride && !property.isDefaultOverride) { hasPrefabOverride = true; break; } } } var coupledComponent = targetComponent.GetCoupledComponent(); if (!hasPrefabOverride && coupledComponent != null) { using (var so = new SerializedObject(coupledComponent)) { SerializedProperty property = so.GetIterator(); while (property.Next(property.hasChildren)) { if (property.isInstantiatedPrefab && property.prefabOverride && !property.isDefaultOverride) { hasPrefabOverride = true; break; } } } } // Handle modified component. if (hasPrefabOverride) { bool isObjectOverrideAllDefaultOverridesComparedToOriginalSource = PrefabUtility.IsObjectOverrideAllDefaultOverridesComparedToOriginalSource(targetObject); PrefabUtility.HandleApplyRevertMenuItems( "Modified Component", targetObject, (menuItemContent, sourceObject, instanceOrAssetObject) => { TargetChoiceHandler.ObjectInstanceAndSourcePathInfo info = new TargetChoiceHandler.ObjectInstanceAndSourcePathInfo(); info.instanceObject = targetObject; info.assetPath = AssetDatabase.GetAssetPath(sourceObject); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceObject); bool isPersistent = EditorUtility.IsPersistent(instanceOrAssetObject); if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || (!isPersistent && !PrefabUtility.HasApplicableObjectOverridesForTarget(instanceOrAssetObject, rootObject, false))) { pm.AddDisabledItem(menuItemContent); } else { pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabObjectOverride, info); } }, (menuItemContent) => { pm.AddItem(menuItemContent, false, TargetChoiceHandler.RevertPrefabObjectOverride, targetObject); }, isObjectOverrideAllDefaultOverridesComparedToOriginalSource ); } } } pm.ObjectContextDropDown(position, context, contextUserData); ResetMouseDown(); }