void CalculatePrefabStatus() { m_PlayModeObjects = false; m_IsAsset = false; m_ImmutableSelf = false; m_ImmutableSourceAsset = false; m_IsDisconnected = false; m_IsMissing = false; m_IsPrefabInstanceAnyRoot = true; m_IsPrefabInstanceOutermostRoot = true; m_AllOfSamePrefabType = true; PrefabAssetType firstType = PrefabUtility.GetPrefabAssetType(targets[0]); PrefabInstanceStatus firstStatus = PrefabUtility.GetPrefabInstanceStatus(targets[0]); foreach (var o in targets) { var go = (GameObject)o; PrefabAssetType type = PrefabUtility.GetPrefabAssetType(go); PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go); if (type != firstType || status != firstStatus) { m_AllOfSamePrefabType = false; } if (Application.IsPlaying(go)) { m_PlayModeObjects = true; } if (!PrefabUtility.IsAnyPrefabInstanceRoot(go)) { m_IsPrefabInstanceAnyRoot = false; // Conservative is false if any is false } if (!m_IsPrefabInstanceAnyRoot || !PrefabUtility.IsOutermostPrefabInstanceRoot(go)) { m_IsPrefabInstanceOutermostRoot = false; // Conservative is false if any is false } if (PrefabUtility.IsPartOfPrefabAsset(go)) { m_IsAsset = true; // Conservative is true if any is true } if (m_IsAsset && PrefabUtility.IsPartOfImmutablePrefab(go)) { m_ImmutableSelf = true; // Conservative is true if any is true } GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot(go); if (originalSourceOrVariant != null && PrefabUtility.IsPartOfImmutablePrefab(originalSourceOrVariant)) { m_ImmutableSourceAsset = true; // Conservative is true if any is true } if (PrefabUtility.IsDisconnectedFromPrefabAsset(go)) { m_IsDisconnected = true; } if (PrefabUtility.IsPrefabAssetMissing(go)) { m_IsMissing = true; } } }
private void DoPrefabButtons(GameObject go) { // @TODO: If/when we support multi-editing of prefab/model instances, // handle it here. Only show prefab bar if all are same type? if (!m_IsPrefabInstanceAnyRoot) { return; } using (new EditorGUI.DisabledScope(EditorApplication.isPlayingOrWillChangePlaymode && PrefabStageUtility.GetPrefabStage(go) == null)) { EditorGUILayout.BeginHorizontal(s_Styles.prefabButtonsHorizontalLayout); // Prefab information PrefabAssetType prefabType = PrefabUtility.GetPrefabAssetType(go); PrefabInstanceStatus instanceStatus = PrefabUtility.GetPrefabInstanceStatus(go); GUIContent prefixLabel; if (targets.Length > 1) { prefixLabel = s_Styles.goTypeLabelMultiple; } else { prefixLabel = s_Styles.goTypeLabel[(int)prefabType, (int)instanceStatus]; } if (prefixLabel != null) { EditorGUILayout.BeginHorizontal(GUILayout.Width(kIconSize + s_Styles.tagFieldWidth)); GUILayout.FlexibleSpace(); if (PrefabUtility.IsDisconnectedFromPrefabAsset(go) || PrefabUtility.IsPrefabAssetMissing(go)) { GUI.contentColor = GUI.skin.GetStyle("CN StatusWarn").normal.textColor; GUILayout.Label(prefixLabel, EditorStyles.whiteLabel, GUILayout.ExpandWidth(false)); GUI.contentColor = Color.white; } else { GUILayout.Label(prefixLabel, GUILayout.ExpandWidth(false)); } EditorGUILayout.EndHorizontal(); } if (targets.Length > 1) { GUILayout.Label("Instance Management Disabled", s_Styles.instanceManagementInfo); } else { if (!PrefabUtility.IsPrefabAssetMissing(go)) { if (prefabType == PrefabAssetType.Model) { // Open Model Prefab if (GUILayout.Button("Open", "MiniButtonLeft")) { GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target); AssetDatabase.OpenAsset(asset); GUIUtility.ExitGUI(); } } else { // Open non-Model Prefab using (new EditorGUI.DisabledScope(m_ImmutableSourceAsset)) { if (GUILayout.Button("Open", "MiniButtonLeft")) { GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target); PrefabStageUtility.OpenPrefab(AssetDatabase.GetAssetPath(asset), (GameObject)target, StageNavigationManager.Analytics.ChangeType.EnterViaInstanceInspectorOpenButton); GUIUtility.ExitGUI(); } } } // Select prefab if (GUILayout.Button("Select", "MiniButtonRight")) { Selection.activeObject = PrefabUtility.GetOriginalSourceOrVariantRoot(target); // Because of legacy prefab references we have to have this extra step // to make sure we ping the prefab asset correctly. // Reason is that scene files created prior to making prefabs CopyAssets // will reference prefabs as if they are serialized assets. Those references // works fine but we are not able to ping objects loaded directly from the asset // file, so we have to make sure we ping the metadata version of the prefab. var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject); Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(assetPath); EditorGUIUtility.PingObject(Selection.activeObject); } // Should be EditorGUILayout.Space, except it does not have ExpandWidth set to false. // Maybe we can change that? GUILayoutUtility.GetRect(6, 6, GUILayout.ExpandWidth(false)); // Reserve space regardless of whether the button is there or not to avoid jumps in button sizes. Rect rect = GUILayoutUtility.GetRect(s_Styles.overridesContent, s_Styles.overridesDropdown); if (m_IsPrefabInstanceOutermostRoot) { if (EditorGUI.DropdownButton(rect, s_Styles.overridesContent, FocusType.Passive)) { PopupWindow.Show(rect, new PrefabOverridesWindow(go)); GUIUtility.ExitGUI(); } } } } EditorGUILayout.EndHorizontal(); } }