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; } } }
void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item) { item.showPrefabModeButton = false; GameObject go = item.objectPPTR as GameObject; if (go == null) { return; } if (!PrefabUtility.IsPartOfAnyPrefab(go)) { return; } if (!PrefabUtility.IsAnyPrefabInstanceRoot(go)) { return; } // Don't show button if prefab asset is missing if (PrefabUtility.GetPrefabInstanceStatus(go) == PrefabInstanceStatus.Connected) { var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go); if (source == null) { return; } // Don't show buttons for model prefabs but allow buttons for other immutables if (PrefabUtility.IsPartOfModelPrefab(source)) { return; } } else if (PrefabUtility.GetPrefabInstanceHandle(go) == null) { return; } else { var assetPath = PrefabUtility.GetAssetPathOfSourcePrefab(go); var broken = AssetDatabase.LoadMainAssetAtPath(assetPath) as BrokenPrefabAsset; if (broken == null || !broken.isPrefabFileValid) { return; } } item.showPrefabModeButton = true; }
void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item) { item.showPrefabModeButton = false; GameObject go = item.objectPPTR as GameObject; if (go == null) { return; } if (!PrefabUtility.IsPartOfAnyPrefab(go)) { return; } if (!PrefabUtility.IsAnyPrefabInstanceRoot(go)) { return; } // Don't show button for disconnected prefab instances and if prefab asset is missing if (PrefabUtility.GetPrefabInstanceStatus(go) != PrefabInstanceStatus.Connected) { return; } var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go); if (source == null) { return; } // Don't show buttons for model prefabs but allow buttons for other immutables if (PrefabUtility.IsPartOfModelPrefab(source)) { return; } item.showPrefabModeButton = true; }
void CalculatePrefabStatus() { m_IsPrefabInstanceAnyRoot = false; m_IsAsset = false; m_AllOfSamePrefabType = true; PrefabAssetType firstType = PrefabUtility.GetPrefabAssetType(targets[0]); PrefabInstanceStatus firstStatus = PrefabUtility.GetPrefabInstanceStatus(targets[0]); foreach (GameObject go in targets) { PrefabAssetType type = PrefabUtility.GetPrefabAssetType(go); PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go); if (type != firstType || status != firstStatus) { m_AllOfSamePrefabType = false; } if (PrefabUtility.IsAnyPrefabInstanceRoot(go)) { m_IsPrefabInstanceAnyRoot = true; } if (m_IsPrefabInstanceAnyRoot) { m_IsPrefabInstanceOutermostRoot = PrefabUtility.IsOutermostPrefabInstanceRoot(go); } if (PrefabUtility.IsPartOfPrefabAsset(go)) { m_IsAsset = true; } if (m_IsAsset && PrefabUtility.IsPartOfImmutablePrefab(go)) { m_ImmutableSelf = true; } GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot(go); if (originalSourceOrVariant != null && PrefabUtility.IsPartOfImmutablePrefab(originalSourceOrVariant)) { m_ImmutableSourceAsset = true; } } }
void SetPrefabModeButtonVisibility(GameObjectTreeViewItem item) { item.showPrefabModeButton = false; GameObject go = item.objectPPTR as GameObject; if (go == null) { return; } if (!PrefabUtility.IsPartOfAnyPrefab(go)) { return; } if (!PrefabUtility.IsAnyPrefabInstanceRoot(go)) { return; } // Don't show button for disconnected prefab instances and if prefab asset is missing if (PrefabUtility.GetPrefabInstanceStatus(go) != PrefabInstanceStatus.Connected) { return; } // We can't simply check if the go is part of an immutable prefab, since that would check the asset of the // outermost prefab this go is part of. Instead we have to check original source or variant root // - the same one that would get opened if clicking the arrow. var source = PrefabUtility.GetOriginalSourceOrVariantRoot(go); if (source == null || PrefabUtility.IsPartOfImmutablePrefab(source)) { return; } item.showPrefabModeButton = true; }
private void DoPrefabButtons() { if (!m_IsPrefabInstanceAnyRoot || m_IsAsset) { return; } using (new EditorGUI.DisabledScope(m_PlayModeObjects)) { EditorGUILayout.BeginHorizontal(Styles.prefabButtonsHorizontalLayout); // Prefab information PrefabAssetType singlePrefabType = PrefabUtility.GetPrefabAssetType(target); PrefabInstanceStatus singleInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(target); GUIContent prefixLabel; if (targets.Length > 1) { prefixLabel = Styles.goTypeLabelMultiple; } else { prefixLabel = Styles.goTypeLabel[(int)singlePrefabType, (int)singleInstanceStatus]; } if (prefixLabel != null) { EditorGUILayout.BeginHorizontal(GUILayout.Width(kIconSize + Styles.tagFieldWidth)); GUILayout.FlexibleSpace(); if (m_IsDisconnected || m_IsMissing) { 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 (!m_IsMissing) { using (new EditorGUI.DisabledScope(targets.Length > 1)) { if (singlePrefabType == PrefabAssetType.Model) { // Open Model Prefab if (GUILayout.Button(Styles.openString, EditorStyles.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(Styles.openString, EditorStyles.miniButtonLeft)) { GameObject asset = PrefabUtility.GetOriginalSourceOrVariantRoot(target); PrefabStageUtility.OpenPrefab(AssetDatabase.GetAssetPath(asset), (GameObject)target, StageNavigationManager.Analytics.ChangeType.EnterViaInstanceInspectorOpenButton); GUIUtility.ExitGUI(); } } } } // Select prefab if (GUILayout.Button(Styles.selectString, EditorStyles.miniButtonRight)) { HashSet <GameObject> selectedAssets = new HashSet <GameObject>(); for (int i = 0; i < targets.Length; i++) { GameObject prefabGo = PrefabUtility.GetOriginalSourceOrVariantRoot(targets[i]); // 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(prefabGo); selectedAssets.Add((GameObject)AssetDatabase.LoadMainAssetAtPath(assetPath)); } Selection.objects = selectedAssets.ToArray(); if (Selection.gameObjects.Length == 1) { 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(Styles.overridesContent, Styles.overridesDropdown); if (m_IsPrefabInstanceOutermostRoot) { if (EditorGUI.DropdownButton(rect, Styles.overridesContent, FocusType.Passive)) { if (targets.Length > 1) { PopupWindow.Show(rect, new PrefabOverridesWindow(targets.Select(e => (GameObject)e).ToArray())); } else { PopupWindow.Show(rect, new PrefabOverridesWindow((GameObject)target)); } GUIUtility.ExitGUI(); } } } EditorGUILayout.EndHorizontal(); } }
internal bool DrawInspector() { serializedObject.Update(); GameObject go = target as GameObject; // Don't let icon be null as it will create null reference exceptions. Texture2D icon = (Texture2D)(Styles.typelessIcon.image); // Leave iconContent to be default if multiple objects not the same type. if (m_AllOfSamePrefabType) { icon = PrefabUtility.GetIconForGameObject(go); } // Can't do this in OnEnable since it will cause Styles static initializer to be called and // access properties on EditorStyles static class before that one has been initialized. if (m_OpenPrefabContent == null) { if (targets.Length == 1) { GameObject originalSourceOrVariant = PrefabUtility.GetOriginalSourceOrVariantRoot((GameObject)target); if (originalSourceOrVariant != null) { m_OpenPrefabContent = new GUIContent( Styles.openPrefab.text, string.Format(Styles.openPrefab.tooltip, originalSourceOrVariant.name)); } } if (m_OpenPrefabContent == null) { m_OpenPrefabContent = new GUIContent(Styles.openPrefab.text); } } EditorGUILayout.BeginHorizontal(); Vector2 dropDownSize = EditorGUI.GetObjectIconDropDownSize(kIconSize, kIconSize); EditorGUI.ObjectIconDropDown(GUILayoutUtility.GetRect(dropDownSize.x, dropDownSize.y, GUILayout.ExpandWidth(false)), targets, true, icon, m_Icon); DrawPostIconContent(); using (new EditorGUI.DisabledScope(m_ImmutableSelf)) { EditorGUILayout.BeginVertical(); { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginHorizontal(GUILayout.Width(Styles.tagFieldWidth)); { GUILayout.FlexibleSpace(); // IsActive EditorGUI.PropertyField( GUILayoutUtility.GetRect(EditorStyles.toggle.padding.left, EditorGUIUtility.singleLineHeight, EditorStyles.toggle, GUILayout.ExpandWidth(false)), m_IsActive, GUIContent.none); } EditorGUILayout.EndHorizontal(); // Disable the name field of root GO in prefab asset using (new EditorGUI.DisabledScope(m_IsAsset && m_IsAssetRoot)) { // Name EditorGUILayout.DelayedTextField(m_Name, GUIContent.none, EditorStyles.boldTextField); } // Static flags toggle DoStaticToggleField(go); // Static flags dropdown DoStaticFlagsDropDown(go); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(EditorGUI.kControlVerticalSpacing); EditorGUILayout.BeginHorizontal(); { // Tag DoTagsField(go); EditorGUILayout.Space(EditorGUI.kDefaultSpacing, false); // Layer DoLayerField(go); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); // Prefab Toolbar if (EditorGUIUtility.comparisonViewMode == EditorGUIUtility.ComparisonViewMode.None) { EditorGUILayout.Space(EditorGUI.kControlVerticalSpacing); DoPrefabButtons(); } serializedObject.ApplyModifiedProperties(); return(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(); } }