private bool IsValidInstance(T element, VerifyPrefabTypeAttribute attribute) { if (element == null) { return(true); } PrefabInstanceStatus prefabType = PrefabUtility.GetPrefabInstanceStatus(element); switch (prefabType) { case PrefabInstanceStatus.NotAPrefab: return(IsFlagSet(attribute.PrefabType, VerifyPrefabTypeFlags.NotAPrefab)); case PrefabInstanceStatus.Connected: return(IsFlagSet(attribute.PrefabType, VerifyPrefabTypeFlags.Connected)); case PrefabInstanceStatus.Disconnected: return(IsFlagSet(attribute.PrefabType, VerifyPrefabTypeFlags.Disconnected)); case PrefabInstanceStatus.MissingAsset: return(IsFlagSet(attribute.PrefabType, VerifyPrefabTypeFlags.MissingAsset)); } return(false); }
public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect) { #if UNITY_2018_3_OR_NEWER PrefabInstanceStatus prefabStatus = PrefabUtility.GetPrefabInstanceStatus(gameObject); if (prefabStatus == PrefabInstanceStatus.MissingAsset || prefabStatus == PrefabInstanceStatus.Disconnected) { QColorUtils.setColor(inactiveColor); GUI.DrawTexture(rect, prefabTexture); QColorUtils.clearColor(); } else if (!showPrefabConnectedIcon && prefabStatus != PrefabInstanceStatus.NotAPrefab) { QColorUtils.setColor(activeColor); GUI.DrawTexture(rect, prefabTexture); QColorUtils.clearColor(); } #else PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); if (prefabType == PrefabType.MissingPrefabInstance || prefabType == PrefabType.DisconnectedPrefabInstance || prefabType == PrefabType.DisconnectedModelPrefabInstance) { QColorUtils.setColor(inactiveColor); GUI.DrawTexture(rect, prefabTexture); QColorUtils.clearColor(); } else if (!showPrefabConnectedIcon && prefabType != PrefabType.None) { QColorUtils.setColor(activeColor); GUI.DrawTexture(rect, prefabTexture); QColorUtils.clearColor(); } #endif }
bool FindClone(AmplifyColorBase effect) { #if UNITY_2018_1_OR_NEWER GameObject effectPrefab = PrefabUtility.GetCorrespondingObjectFromSource(effect.gameObject) as GameObject; PrefabAssetType effectPrefabType = PrefabUtility.GetPrefabAssetType(effect.gameObject); PrefabInstanceStatus effectPrefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(effect.gameObject); bool effectIsPrefab = (effectPrefabType != PrefabAssetType.NotAPrefab && effectPrefabInstanceStatus == PrefabInstanceStatus.NotAPrefab); #else GameObject effectPrefab = PrefabUtility.GetPrefabParent(effect.gameObject) as GameObject; PrefabType effectPrefabType = PrefabUtility.GetPrefabType(effect.gameObject); bool effectIsPrefab = (effectPrefabType != PrefabType.None && effectPrefabType != PrefabType.PrefabInstance); #endif bool effectHasPrefab = (effectPrefab != null); AmplifyColorBase[] all = Resources.FindObjectsOfTypeAll(typeof(AmplifyColorBase)) as AmplifyColorBase[]; bool foundClone = false; foreach (AmplifyColorBase other in all) { if (other == effect || other.SharedInstanceID != effect.SharedInstanceID) { // skip: same effect or already have different ids continue; } #if UNITY_2018_1_OR_NEWER GameObject otherPrefab = PrefabUtility.GetCorrespondingObjectFromSource(other.gameObject) as GameObject; PrefabAssetType otherPrefabType = PrefabUtility.GetPrefabAssetType(other.gameObject); PrefabInstanceStatus otherPrefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(other.gameObject); bool otherIsPrefab = (otherPrefabType != PrefabAssetType.NotAPrefab && otherPrefabInstanceStatus == PrefabInstanceStatus.NotAPrefab); #else GameObject otherPrefab = PrefabUtility.GetPrefabParent(other.gameObject) as GameObject; PrefabType otherPrefabType = PrefabUtility.GetPrefabType(other.gameObject); bool otherIsPrefab = (otherPrefabType != PrefabType.None && otherPrefabType != PrefabType.PrefabInstance); #endif bool otherHasPrefab = (otherPrefab != null); if (otherIsPrefab && effectHasPrefab && effectPrefab == other.gameObject) { // skip: other is a prefab and effect's prefab is other continue; } if (effectIsPrefab && otherHasPrefab && otherPrefab == effect.gameObject) { // skip: effect is a prefab and other's prefab is effect continue; } if (!effectIsPrefab && !otherIsPrefab && effectHasPrefab && otherHasPrefab && effectPrefab == otherPrefab) { // skip: both aren't prefabs and both have the same parent prefab continue; } foundClone = true; } return(foundClone); }
private void CheckSceneInfo(bool revert) { sceneCFG = FindObjectOfType <SceneCFG>(); if (sceneCFG != null) { GameObject root = sceneCFG.gameObject; PrefabInstanceStatus prefabType = PrefabUtility.GetPrefabInstanceStatus(root); if (prefabType == PrefabInstanceStatus.NotAPrefab) { GameObject.DestroyImmediate(root); sceneCFG = null; } else { //重置为已存储的数据 if (revert) { PrefabUtility.RevertPrefabInstance(root, InteractionMode.AutomatedAction); } } } if (sceneCFG == null) { string path = getSceneAssetPrefix() + "/sceneInfo.prefab"; GameObject go = AssetDatabase.LoadAssetAtPath <GameObject>(path); if (go != null) { GameObject root = (GameObject)PrefabUtility.InstantiatePrefab(go); //root=PrefabUtility.ConnectGameObjectToPrefab(root, go); sceneCFG = root.GetComponent <SceneCFG>(); } } }
//Returns a single prefab if and only if it is the only one in the selection private static GameObject GetPrefabOnly(GameObject[] gameObjects) { List <GameObject> prefabs = new List <GameObject>(); foreach (GameObject go in gameObjects) { if (go != null) { PrefabAssetType prefabType = PrefabUtility.GetPrefabAssetType(go); if (prefabType == PrefabAssetType.Model || prefabType == PrefabAssetType.Regular || prefabType == PrefabAssetType.Variant) { PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go); if (status == PrefabInstanceStatus.NotAPrefab) { string path = AssetDatabase.GetAssetPath(go); if (!string.IsNullOrEmpty(path)) { prefabs.Add(go); } } } } } // Only return anything if there is one and only one prefab if (prefabs.Count == 1) { return(prefabs[0]); } return(null); }
void DrawPreviewSection() { DiskMesh diskMesh = ((DiskMesh)target); PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(diskMesh.gameObject); // TODO: @Investigate I thought this should work opposite way, am I using this properly? if (status == PrefabInstanceStatus.NotAPrefab) { return; } showPreview = EditorGUILayout.Foldout(showPreview, "Preview"); if (!showPreview) { return; } diskMesh.PreviewSize = EditorGUILayout.IntField("Size", diskMesh.PreviewSize); diskMesh.PreviewMaxDisks = EditorGUILayout.IntField("Max Disks", diskMesh.PreviewMaxDisks); if (GUILayout.Button("Preview")) { diskMesh.Build(diskMesh.PreviewSize, diskMesh.PreviewMaxDisks); } }
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; } } }
/// <summary> /// Returns true if the specified gameObject is a prefab instance (connected to a prefab) /// </summary> public static bool IsPrefabInstance(GameObject gameObject) { // TODO CHANGED: Unity API has been changed. PrefabInstanceStatus instanceStatus = PrefabUtility.GetPrefabInstanceStatus(gameObject); return(instanceStatus == PrefabInstanceStatus.Connected); //return PrefabUtility.GetPrefabType(gameObject) == PrefabType.PrefabInstance; }
// Some prefab overrides are not handled by Undo.RecordObject or EditorUtility.SetDirty. // eg. adding an item to an array/list on a prefab instance updates that the instance // has a different array count than the prefab, but not any data about the added thing private static void HandlePrefabInstance(GameObject gameObject) { //var prefabType = PrefabUtility.GetPrefabType(gameObject); PrefabInstanceStatus prefabType = PrefabUtility.GetPrefabInstanceStatus(gameObject); if (prefabType != PrefabInstanceStatus.NotAPrefab) { PrefabUtility.RecordPrefabInstancePropertyModifications(gameObject); } }
public static bool IsPrefab(this GameObject go) { if (go.scene.rootCount == 0) { return(true); } PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(go); return(status == PrefabInstanceStatus.Connected || status == PrefabInstanceStatus.Disconnected); }
protected override T Edit(Rect region, GUIContent label, T element, VerifyPrefabTypeAttribute attribute, fiGraphMetadata metadata) { if (IsValidInstance(element, attribute) == false) { region.height -= Margin; PrefabInstanceStatus actualPrefabType = PrefabUtility.GetPrefabInstanceStatus(element);; EditorGUI.HelpBox(region, "This property needs to be a " + attribute.PrefabType + ", not a " + actualPrefabType, MessageType.Error); } return(element); }
/// <summary> /// Returns the fbx asset on disk corresponding to the same hierarchy as is selected. /// /// Returns go if go is the root of a model prefab. /// Returns the prefab parent of go if it's the root of a model prefab. /// Returns null in all other circumstances. /// </summary> /// <returns>The root of a model prefab asset, or null.</returns> /// <param name="go">A gameobject either in the scene or in the assets folder.</param> internal static GameObject GetFbxAssetOrNull(GameObject go) { // Children of model prefab instances will also have "model prefab instance" // as their prefab type, so it is important that it is the root that is selected. // // e.g. If I have the following hierarchy: // Cube // -- Sphere // // Both the Cube and Sphere will have ModelPrefab as their prefab type. // However, when selecting the Sphere to convert, we don't want to connect it to the // existing FBX but create a new FBX containing just the sphere. if (!PrefabUtility.IsPartOfModelPrefab(go)) { return(null); } PrefabInstanceStatus prefabStatus = PrefabUtility.GetPrefabInstanceStatus(go); switch (prefabStatus) { case PrefabInstanceStatus.Connected: // this is a prefab instance, get the object from source if (PrefabUtility.IsOutermostPrefabInstanceRoot(go)) { return(PrefabUtility.GetCorrespondingObjectFromSource(go) as GameObject); } else { return(null); } case PrefabInstanceStatus.NotAPrefab: // a prefab asset if (go.transform.root.gameObject == go) { return(go); } else { return(null); } default: return(null); } }
/// <summary> /// Draws all countries provinces. /// </summary> void DrawAllProvinceBorders(bool forceRefresh) { if (!gameObject.activeInHierarchy) { return; } if (provincesObj != null && !forceRefresh) { return; } HideProvinces(); if (!_showProvinces || !_drawAllProvinces) { return; } // Workdaround to hang in Unity Editor when enabling this option with prefab #if UNITY_EDITOR #if UNITY_2018_3_OR_NEWER PrefabInstanceStatus prefabStatus = PrefabUtility.GetPrefabInstanceStatus(gameObject); if (prefabStatus != PrefabInstanceStatus.NotAPrefab) { PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } #else PrefabUtility.DisconnectPrefabInstance(gameObject); #endif #endif int numCountries = countries.Length; List <Country> targetCountries = new List <Country> (numCountries); for (int k = 0; k < numCountries; k++) { if (_countries [k].allowShowProvinces) { targetCountries.Add(_countries [k]); } } DrawProvinces(targetCountries, 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; } } }
public override void OnInspectorGUI() { InteractionButton button = target as InteractionButton; bool nonzeroRotation = button.transform.localRotation != Quaternion.identity; bool isRoot = button.transform == button.transform.root; PrefabInstanceStatus objectType = PrefabUtility.GetPrefabInstanceStatus(button.gameObject);//GetPrefabAssetType(button.gameObject); bool isNotAnUninstantiatedPrefab = objectType == PrefabInstanceStatus.NotAPrefab || objectType == PrefabInstanceStatus.Connected || objectType == PrefabInstanceStatus.Disconnected || objectType == PrefabInstanceStatus.MissingAsset; EditorGUILayout.BeginHorizontal(); if ((nonzeroRotation || isRoot) && isNotAnUninstantiatedPrefab) { if (isRoot) { EditorGUILayout.HelpBox("This button has no parent! Buttons do not work without a parent transform.", MessageType.Warning); } else if (nonzeroRotation) { EditorGUILayout.HelpBox("It looks like this button's local rotation is non-zero; would you like to add a parent transform so it depresses along its z-axis?", MessageType.Warning); } if (GUILayout.Button("Add Button\nParent Transform")) { GameObject buttonBaseTransform = new GameObject(button.gameObject.name + " Base"); Undo.RegisterCreatedObjectUndo(buttonBaseTransform, "Created Button Base for " + button.gameObject.name); Undo.SetTransformParent(buttonBaseTransform.transform, button.transform.parent, "Child " + button.gameObject.name + "'s Base to " + button.gameObject.name + "'s Parent"); Undo.RecordObject(buttonBaseTransform, "Set " + target.gameObject.name + "'s Base's Transform's Properties"); buttonBaseTransform.transform.localPosition = button.transform.localPosition; buttonBaseTransform.transform.localRotation = button.transform.localRotation; buttonBaseTransform.transform.localScale = button.transform.localScale; Undo.SetTransformParent(button.transform, buttonBaseTransform.transform, "Child " + button.gameObject.name + " to its Base"); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (!isRoot) { bool isUniform = (button.transform.parent.lossyScale.x.NearlyEquals(button.transform.parent.lossyScale.y) && button.transform.parent.lossyScale.y.NearlyEquals(button.transform.parent.lossyScale.z) && button.transform.parent.lossyScale.x.NearlyEquals(button.transform.parent.lossyScale.z)); if (!isUniform) { EditorGUILayout.HelpBox("This button exists within a non-uniformly scaled space! Please check the parent transforms for non-uniform scale...", MessageType.Warning); } } EditorGUILayout.EndHorizontal(); Rigidbody currentBody = button.GetComponent <Rigidbody>(); RigidbodyConstraints constraints = currentBody.constraints; EditorGUILayout.BeginHorizontal(); if (constraints != RigidbodyConstraints.FreezeRotation) { EditorGUILayout.HelpBox("It looks like this button can freely rotate around one or more axes; would you like to constrain its rotation?", MessageType.Warning); if (GUILayout.Button("Freeze\nRotation")) { Undo.RecordObject(currentBody, "Set " + target.gameObject.name + "'s Rigidbody's Rotation Constraints to be frozen"); currentBody.constraints = RigidbodyConstraints.FreezeRotation; } } EditorGUILayout.EndHorizontal(); base.OnInspectorGUI(); }
public static bool IsInstance(PrefabInstanceStatus status) { return(status != PrefabInstanceStatus.NotAPrefab); }
public static bool IsProperlyConnectedInstance(PrefabInstanceStatus status) { return(status == PrefabInstanceStatus.Connected); }
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(); } }
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(); } }
protected static GameObject getSourcePrefab42019(GameObject gameObject, out bool isSceneObject, out GameObject sourceRoot, out string childPath) { GameObject source; PrefabAssetType assetType = PrefabUtility.GetPrefabAssetType(gameObject); PrefabInstanceStatus status = PrefabUtility.GetPrefabInstanceStatus(gameObject); PrefabStage stage = PrefabStageUtility.GetCurrentPrefabStage(); if (stage != null && stage.IsPartOfPrefabContents(gameObject)) { //编辑场景 isSceneObject = false; childPath = stage.prefabContentsRoot.transform.getChildPath(gameObject.transform); sourceRoot = AssetDatabase.LoadAssetAtPath <GameObject>(stage.prefabAssetPath); Transform sourceTransform = sourceRoot.transform.Find(childPath); if (sourceTransform != null) { source = sourceTransform.gameObject; } else { sourceRoot = null; childPath = string.Empty; return(null); } } else if (string.IsNullOrEmpty(gameObject.scene.path)) { //Assets isSceneObject = false; source = gameObject; sourceRoot = source.transform.root.gameObject; childPath = sourceRoot.transform.getChildPath(source.transform); //switch (assetType) //{ // case PrefabAssetType.Regular: // case PrefabAssetType.Variant: // case PrefabAssetType.Model: // case PrefabAssetType.MissingAsset: // case PrefabAssetType.NotAPrefab: // default: // break; //} } else { //场景物体 switch (status) { case PrefabInstanceStatus.Connected: switch (assetType) { case PrefabAssetType.Regular: case PrefabAssetType.Model: isSceneObject = false; source = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); sourceRoot = source.transform.root.gameObject; childPath = sourceRoot.transform.getChildPath(source.transform); break; case PrefabAssetType.Variant: isSceneObject = false; source = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); sourceRoot = source.transform.root.gameObject; childPath = sourceRoot.transform.getChildPath(source.transform); break; case PrefabAssetType.MissingAsset: case PrefabAssetType.NotAPrefab: default: isSceneObject = true; source = gameObject; sourceRoot = null; childPath = null; break; } break; case PrefabInstanceStatus.NotAPrefab: case PrefabInstanceStatus.MissingAsset: case PrefabInstanceStatus.Disconnected: default: isSceneObject = true; source = gameObject; sourceRoot = null; childPath = null; break; } } return(source); }
void Write(LevelSegment segment, bool forceCopy) { //Check to see if we are currently editing the prefab and if yes (2018.3), just pack everything without rewriting bool isPrefabInstance = false; Object prefabParent = null; #if UNITY_2018_3_OR_NEWER PrefabInstanceStatus instanceStatus = PrefabUtility.GetPrefabInstanceStatus(segment.gameObject); isPrefabInstance = instanceStatus == PrefabInstanceStatus.Connected; if (isPrefabInstance) { prefabParent = PrefabUtility.GetCorrespondingObjectFromSource(segment.gameObject); } #else PrefabType prefabType = PrefabUtility.GetPrefabType(segment.gameObject); isPrefabInstance = prefabType == PrefabType.PrefabInstance; if (isPrefabInstance) { prefabParent = PrefabUtility.GetPrefabParent(segment.gameObject); } #endif if (!forceCopy && prefabParent != null) { segment.EditorPack(); #if DREAMTECK_SPLINES for (int i = 0; i < splines.Length; i++) { if (splines[i] != null) { DSSplineDrawer.UnregisterComputer(splines[i]); } } #endif #if UNITY_2018_3_OR_NEWER Selection.activeGameObject = PrefabUtility.SaveAsPrefabAsset(segment.gameObject, AssetDatabase.GetAssetPath(prefabParent)); #else PrefabUtility.ReplacePrefab(segment.gameObject, prefabParent, ReplacePrefabOptions.ConnectToPrefab); #endif Undo.DestroyObjectImmediate(segment.gameObject); } else { relativePath = EditorPrefs.GetString("LevelSegmentEditor.relativePath", "/"); if (prefabParent != null) { relativePath = AssetDatabase.GetAssetPath(prefabParent); if (relativePath.StartsWith("Assets")) { relativePath = relativePath.Substring("Assets".Length); } relativePath = System.IO.Path.GetDirectoryName(relativePath); } string path = EditorUtility.SaveFilePanel("Save Prefab", Application.dataPath + relativePath, segment.name, "prefab"); if (path.StartsWith(Application.dataPath) && System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path))) { relativePath = path.Substring(Application.dataPath.Length); segment.EditorPack(); #if DREAMTECK_SPLINES for (int i = 0; i < splines.Length; i++) { if (splines[i] != null) { DSSplineDrawer.UnregisterComputer(splines[i]); } } #endif #if UNITY_2018_3_OR_NEWER if (isPrefabInstance) { PrefabUtility.UnpackPrefabInstance(segment.gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); } PrefabUtility.SaveAsPrefabAsset(segment.gameObject, "Assets" + relativePath); #else if (isPrefabInstance) { PrefabUtility.DisconnectPrefabInstance(segment.gameObject); } PrefabUtility.CreatePrefab("Assets" + relativePath, segment.gameObject); #endif Undo.DestroyObjectImmediate(segment.gameObject); EditorPrefs.SetString("LevelSegmentEditor.relativePath", System.IO.Path.GetDirectoryName(relativePath)); } else { if (path != "" && !path.StartsWith(Application.dataPath)) { EditorUtility.DisplayDialog("Path Error", "Please select a path inside this project's Assets folder", "OK"); } } } }
private void OnGUI() { EditorGUILayout.HelpBox( "This tool replaces the currently selected GameObjects with instances of the specified Prefab.", MessageType.None); EditorGUILayout.Space(); GUILayout.Label("Selections:", EditorStyles.boldLabel); EditorGUILayout.BeginVertical(); foreach (var selectedObject in Selection.gameObjects) { GUILayout.Label(selectedObject.name); } EditorGUILayout.EndVertical(); GUILayout.Label("Prefab Object", EditorStyles.boldLabel); this.prefabObject = EditorGUILayout.ObjectField(this.prefabObject, typeof(GameObject), true) as GameObject; if (!IsGameObjectPrefab(this.prefabObject)) { EditorGUILayout.HelpBox("GameObject is not a Prefab or Prefab Instance", MessageType.Error); return; } if (Selection.activeTransform == null) { EditorGUILayout.HelpBox("No GameObjects selected", MessageType.Warning); return; } if (GUILayout.Button("Replace Selected")) { if (this.prefabObject != null) { Transform transformToSelect = null; foreach (Transform transformToCopy in Selection.transforms) { GameObject instanceObj = null; //GameObject prefab = PrefabUtility.GetPrefabParent(this.prefabObject) as GameObject; GameObject prefab = PrefabUtility.GetCorrespondingObjectFromSource(this.prefabObject) as GameObject; //var prefabType = PrefabUtility.GetPrefabType(this.prefabObject); PrefabAssetType pAssetType = PrefabUtility.GetPrefabAssetType(prefabObject); PrefabInstanceStatus pInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(prefabObject); //if (prefabType == PrefabType.PrefabInstance) if (pInstanceStatus != PrefabInstanceStatus.NotAPrefab) { // Copy instance settings into selected object if the selection is a prefab instance instanceObj = (GameObject)PrefabUtility.InstantiatePrefab(prefab); PrefabUtility.SetPropertyModifications( instanceObj, PrefabUtility.GetPropertyModifications(this.prefabObject)); } //else if (prefabType == PrefabType.Prefab) else if (pAssetType != PrefabAssetType.NotAPrefab) { // Instantiate a new prefab instanceObj = (GameObject)PrefabUtility.InstantiatePrefab(this.prefabObject); } else { Debug.LogError("Supplied GameObject is of an unrecognized type."); return; } Undo.RegisterCreatedObjectUndo(instanceObj, "created prefab"); // Apply previous transform settings to the new one Transform createdTransform = instanceObj.transform; createdTransform.position = transformToCopy.position; createdTransform.rotation = transformToCopy.rotation; createdTransform.localScale = transformToCopy.localScale; createdTransform.parent = transformToCopy.parent; // Keep the old name createdTransform.name = transformToCopy.name; // Restore sibling index createdTransform.SetSiblingIndex(transformToCopy.GetSiblingIndex()); // Flag transform to reselect if (transformToCopy == Selection.activeTransform) { transformToSelect = createdTransform; } } // Destroy old game objects foreach (GameObject go in Selection.gameObjects) { Undo.DestroyObjectImmediate(go); } if (transformToSelect != null) { Selection.activeTransform = transformToSelect; } } } }
void OnWizardCreate() { if (replacement == null) { EditorUtility.DisplayDialog("Error: Replace Selection", "No replacement selected", "Ok"); return; } Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.OnlyUserModifiable); Debug.Log("Replacing " + transforms.Length, this); Undo.SetCurrentGroupName("Replace Selection"); int group = Undo.GetCurrentGroup(); PrefabAssetType prefabAssetType = PrefabUtility.GetPrefabAssetType(replacement); PrefabInstanceStatus prefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(replacement); List <GameObject> allCreated = new List <GameObject>(); foreach (Transform t in transforms) { GameObject created; if (prefabAssetType == PrefabAssetType.NotAPrefab) { created = (GameObject)Editor.Instantiate(replacement); } else { if (prefabInstanceStatus == PrefabInstanceStatus.NotAPrefab) { created = (GameObject)PrefabUtility.InstantiatePrefab(replacement, t.parent); } else { GameObject prefabParent = PrefabUtility.GetCorrespondingObjectFromSource(replacement) as GameObject; created = (GameObject)PrefabUtility.InstantiatePrefab(prefabParent); PrefabUtility.SetPropertyModifications(created, PrefabUtility.GetPropertyModifications(replacement)); } } Undo.RegisterCreatedObjectUndo(created, "Replacement instance"); created.name = replacement.name; created.transform.parent = t.parent; created.transform.localPosition = t.localPosition; created.transform.localScale = t.localScale; created.transform.localRotation = t.localRotation; allCreated.Add(created); } if (!keep) { foreach (GameObject g in Selection.gameObjects) { Undo.DestroyObjectImmediate(g); } } Selection.objects = allCreated.ToArray(); Undo.CollapseUndoOperations(group); }
/// <summary> /// Returns true when a GameObject is instanced from a prefab. False otherwise. /// </summary> /// <param name="gameObject">The GameObject to be checked.</param> /// <returns>True when a GameObject is instanced from a prefab. False otherwise.</returns> public static bool IsPrefabInstance(this GameObject gameObject) { PrefabInstanceStatus prefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(gameObject); return (prefabInstanceStatus != PrefabInstanceStatus.NotAPrefab); }