#pragma warning restore 0618 // Type or member is obsolete internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, Object targetPrefab) { if (gameObjects == null) { throw new ArgumentNullException("gameObjects"); } if (gameObjects.Length == 0) { throw new ArgumentException("gameObjects array is empty"); } if (targetPrefab == null) { throw new ArgumentNullException("targetPrefab"); } if (!PrefabUtility.IsPartOfPrefabAsset(targetPrefab)) { throw new ArgumentException("Target Prefab has to be a Prefab Asset"); } Object targetPrefabInstance = null; var targetPrefabObject = PrefabUtility.GetPrefabAssetHandle(targetPrefab); foreach (GameObject go in gameObjects) { if (go == null) { throw new ArgumentException("GameObject in input 'gameObjects' array is null"); } if (EditorUtility.IsPersistent(go)) // Prefab asset { throw new ArgumentException("Game object is part of a prefab"); } var parentPrefabInstance = GetParentPrefabInstance(go); if (parentPrefabInstance == null) { throw new ArgumentException("GameObject is not (directly) parented under a target Prefab instance."); } if (targetPrefabInstance == null) { targetPrefabInstance = parentPrefabInstance; if (!IsPrefabInstanceObjectOf(go.transform.parent, targetPrefabObject)) { throw new ArgumentException("GameObject is not parented under a target Prefab instance."); } } else { if (parentPrefabInstance != targetPrefabInstance) { throw new ArgumentException("GameObjects must be parented under the same Prefab instance."); } } if (PrefabUtility.IsPartOfNonAssetPrefabInstance(go)) { var correspondingGO = PrefabUtility.GetCorrespondingObjectFromSource(go); var correspondingGOPrefabObject = PrefabUtility.GetPrefabAssetHandle(correspondingGO); if (targetPrefabObject == correspondingGOPrefabObject) { throw new ArgumentException("GameObject is already part of target prefab"); } } } string prefabGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetPrefab)); if (!VerifyNestingFromScript(gameObjects, prefabGUID, null)) { throw new ArgumentException("Cyclic nesting detected"); } AddGameObjectsToPrefabAndConnect_Internal(gameObjects, targetPrefab); }
public static Object GetPrefabParent(Object source) { return(PrefabUtility.GetCorrespondingObjectFromSource(source)); }
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; } } } // Handle modified component. if (hasPrefabOverride) { bool defaultOverrides = PrefabUtility.IsObjectOverrideAllDefaultOverridesComparedToAnySource(targetObject); PrefabUtility.HandleApplyRevertMenuItems( "Modified Component", targetObject, (menuItemContent, sourceObject) => { TargetChoiceHandler.ObjectInstanceAndSourcePathInfo info = new TargetChoiceHandler.ObjectInstanceAndSourcePathInfo(); info.instanceObject = targetObject; info.assetPath = AssetDatabase.GetAssetPath(sourceObject); GameObject rootObject = PrefabUtility.GetRootGameObject(sourceObject); if (!PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(rootObject) || EditorUtility.IsPersistent(targetObject)) { pm.AddDisabledItem(menuItemContent); } else { pm.AddItem(menuItemContent, false, TargetChoiceHandler.ApplyPrefabObjectOverride, info); } }, (menuItemContent) => { pm.AddItem(menuItemContent, false, TargetChoiceHandler.RevertPrefabObjectOverride, targetObject); }, defaultOverrides ); } } } pm.ObjectContextDropDown(position, context, contextUserData); ResetMouseDown(); }
bool ApplyAll() { // Collect Prefab Asset paths and also check if there's more than one of the same. HashSet <string> prefabAssetPaths = new HashSet <string>(); bool multipleOfSame = false; for (int i = 0; i < m_SelectedGameObjects.Length; i++) { string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(m_SelectedGameObjects[i]); if (prefabAssetPaths.Contains(prefabAssetPath)) { multipleOfSame = true; } else { prefabAssetPaths.Add(prefabAssetPath); } } // If more than one instance of the same Prefab Asset, show dialog to user. if (multipleOfSame && !EditorUtility.DisplayDialog( L10n.Tr("Multiple instances of same Prefab Asset"), L10n.Tr("Multiple instances of the same Prefab Asset were detected. Potentially conflicting overrides will be applied sequentially and will overwrite each other."), L10n.Tr("OK"), L10n.Tr("Cancel"))) { return(false); } // Make sure assets are checked out in version control. if (!PrefabUtility.PromptAndCheckoutPrefabIfNeeded(prefabAssetPaths.ToArray(), PrefabUtility.SaveVerb.Apply)) { return(false); } var undoStructs = new List <ApplyAllUndo>(); var actionName = "ApplyAll"; for (var i = 0; i < m_SelectedGameObjects.Length; i++) { var us = new ApplyAllUndo(); us.correspondingSourceObject = (GameObject)PrefabUtility.GetCorrespondingObjectFromSource(m_SelectedGameObjects[i]); Undo.RegisterFullObjectHierarchyUndo(us.correspondingSourceObject, actionName); // handles changes to existing objects and object what will be deleted but not objects that are created GameObject prefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(m_SelectedGameObjects[i]); Undo.RegisterFullObjectHierarchyUndo(prefabInstanceRoot, actionName); us.prefabHierarchy = new HashSet <int>(); PrefabUtility.GetObjectListFromHierarchy(us.prefabHierarchy, us.correspondingSourceObject); undoStructs.Add(us); } // Apply sequentially. AssetDatabase.StartAssetEditing(); try { foreach (var t in m_SelectedGameObjects) { PrefabUtility.ApplyPrefabInstance(t, InteractionMode.UserAction); } } finally { AssetDatabase.StopAssetEditing(); } foreach (var t in undoStructs) { PrefabUtility.RegisterNewObjects(t.correspondingSourceObject, t.prefabHierarchy, actionName); } EditorUtility.ForceRebuildInspectors(); return(true); }