internal void OnAwake(HierarchyFolder hierarchyFolder) { if (!initialized) { Initialize(); } if (EditorApplication.isPlayingOrWillChangePlaymode && !hierarchyFolder.gameObject.IsPrefabAssetOrOpenInPrefabStage()) { PlayModeStripper.OnSceneObjectAwake(hierarchyFolder.gameObject); return; } // Hide flags are reset for all scene instances on scene reload, so we need to reapply them. hierarchyFolder.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable; var transform = hierarchyFolder.transform; if (transform.hideFlags == HideFlags.None) { // Don't hide transform in prefabs or prefab instances to avoid internal Unity exceptions if (!transform.gameObject.IsPrefabAssetOrInstance()) { transform.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable; } else { transform.hideFlags = HideFlags.NotEditable; } } Register(hierarchyFolder); }
private static void HandlePrefabOrPrefabInstanceStateLocking(HierarchyFolder hierarchyFolder, bool isPrefabAsset) { var transform = hierarchyFolder.transform; transform.hideFlags = HideFlags.NotEditable; var gameObject = transform.gameObject; if (gameObject.layer != DefaultLayer) { gameObject.layer = DefaultLayer; } hierarchyFolder.hideFlags = HideFlags.HideInInspector; if (!isPrefabAsset) { return; } if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder)) { HierarchyFolderUtility.UnmakeHierarchyFolder(gameObject, hierarchyFolder); return; } HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(transform); }
public static void FlattenAndDestroyHierarchyFolder([NotNull] HierarchyFolder hierarchyFolder) { bool wasStripping = NowStripping; NowStripping = true; var transform = hierarchyFolder.transform; int childCount = transform.childCount; var children = new Transform[childCount]; for (int n = 0; n < childCount; n++) { children[n] = transform.GetChild(n); } var hierarchyFolderParent = transform.parent; int setSiblingIndex = transform.GetSiblingIndex() + 1; #if DEV_MODE && DEBUG_STRIP_FOLDER Debug.Log("Stripping " + transform.name + " with " + childCount + " children..."); #endif // Only set children active after hierarchy folder has been stripped, // so that they cannot get a reference to it before it has been destroyed List <GameObject> setChildrenActiveDelayed = null; for (int n = 0; n < childCount; n++) { var child = children[n]; if (!transform.gameObject.activeSelf && child.gameObject.activeSelf && Application.isPlaying) { if (setChildrenActiveDelayed == null) { setChildrenActiveDelayed = new List <GameObject>(); } child.gameObject.SetActive(false); setChildrenActiveDelayed.Add(child.gameObject); } child.SetParent(hierarchyFolderParent, true); child.SetSiblingIndex(setSiblingIndex); setSiblingIndex++; } // Using DestroyImmediate instead of Destroy even in builds so that other scripts won't be aware of the hierarchy folders ever having existed. Object.DestroyImmediate(transform.gameObject, true); if (setChildrenActiveDelayed != null) { for (int n = 0, count = setChildrenActiveDelayed.Count; n < count; n++) { setChildrenActiveDelayed[n].SetActive(true); } } NowStripping = wasStripping; }
private void Deregister(HierarchyFolder hierarchyFolder) { hierarchyFolders.Remove(hierarchyFolder); #if DEV_MODE && DEBUG_DEREGISTER Debug.Log("Deregister: " + (hierarchyFolder == null ? "null" : "\"" + hierarchyFolder.name + "\"") + "\nTotal Count: " + hierarchyFolders.Count, hierarchyFolder); #endif }
internal void OnValidate(HierarchyFolder hierarchyFolder) { if (!initialized) { Initialize(); } Register(hierarchyFolder); }
internal void OnDestroy(HierarchyFolder hierarchyFolder) { if (!initialized) { Initialize(); } Deregister(hierarchyFolder); }
public static bool HasSupernumeraryComponents([NotNull] HierarchyFolder hierarchyFolder) { hierarchyFolder.GetComponents(ReusableComponentsList); // A hierarchy folder should only have Transform (or RectTransform) and HierarchyFolder components. bool tooManyComponents = ReusableComponentsList.Count > 2; ReusableComponentsList.Clear(); return(tooManyComponents); }
private static int GetDepth([NotNull] HierarchyFolder hierarchyFolder) { int depth = 0; for (var parent = hierarchyFolder.transform.parent; parent != null; parent = parent.parent) { depth++; } return(depth); }
public static void UnmakeHierarchyFolder([NotNull] GameObject gameObject, [CanBeNull] HierarchyFolder hierarchyFolder) { #if DEV_MODE && DEBUG_UNMAKE_HIERARCHY_FOLDER Debug.Log("UnmakeHierarchyFolder(" + gameObject.name + ")"); #endif if (hierarchyFolder != null) { #if UNITY_EDITOR #if UNITY_2018_3_OR_NEWER if (!Application.isPlaying || UnityEditor.PrefabUtility.GetPrefabAssetType(gameObject) != UnityEditor.PrefabAssetType.NotAPrefab) #else if (!Application.isPlaying || UnityEditor.PrefabUtility.GetPrefabType(gameObject) == UnityEditor.PrefabType.Prefab) #endif { Object.DestroyImmediate(hierarchyFolder, true); } else #endif { Object.Destroy(hierarchyFolder); } } var preferences = HierarchyFolderPreferences.Get(); string setName = gameObject.name; string prefix = preferences.namePrefix; if (prefix.Length > 0 && setName.StartsWith(prefix, StringComparison.Ordinal)) { setName = setName.Substring(0); } string suffix = preferences.nameSuffix; if (suffix.Length > 0 && setName.EndsWith(setName, StringComparison.Ordinal)) { setName = setName.Substring(0, setName.Length - suffix.Length); } if (preferences.forceNamesUpperCase && setName.Length > 1) { setName = setName[0] + setName.Substring(1).ToLower(); } if (!string.Equals(setName, gameObject.name)) { gameObject.name = setName; #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(gameObject); #endif } var transform = gameObject.transform; transform.hideFlags = HideFlags.None; #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(transform); #endif }
internal void OnReset(HierarchyFolder hierarchyFolder) { if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder)) { Debug.LogWarning("Can't convert GameObject with extraneous components into a Hierarchy Folder.", hierarchyFolder.gameObject); TurnIntoNormalGameObject(hierarchyFolder); return; } var gameObject = hierarchyFolder.gameObject; if (HierarchyFolderPreferences.Get().foldersInPrefabs == HierachyFoldersInPrefabs.NotAllowed) { bool isPrefabInstance = gameObject.IsConnectedPrefabInstance(); if (isPrefabInstance || gameObject.IsPrefabAssetOrOpenInPrefabStage()) { OnHierarchyFolderDetectedOnAPrefabAndNotAllowed(hierarchyFolder, isPrefabInstance); return; } } var transform = hierarchyFolder.transform; HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(transform); // Don't hide transform in prefabs or prefab instances to avoid internal Unity exceptions if (!gameObject.IsPrefabAssetOrInstance()) { transform.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable; } else { transform.hideFlags = HideFlags.NotEditable; } hierarchyFolder.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable; EditorUtility.SetDirty(transform); gameObject.isStatic = true; EditorUtility.SetDirty(hierarchyFolder); var preferences = HierarchyFolderPreferences.Get(); if (preferences.autoNameOnAdd) { if (gameObject.name.Equals("GameObject", StringComparison.Ordinal) || gameObject.name.StartsWith("GameObject (", StringComparison.Ordinal)) { gameObject.name = preferences.defaultName; } else { ApplyNamingPattern(hierarchyFolder); } } EditorUtility.SetDirty(gameObject); }
private static void HandleSceneObjectStateLocking(HierarchyFolder hierarchyFolder) { var transform = hierarchyFolder.transform; transform.hideFlags = HideFlags.HideInInspector; hierarchyFolder.hideFlags = HideFlags.HideInInspector; if (transform.gameObject.layer != DefaultLayer) { transform.gameObject.layer = DefaultLayer; } }
private void UnmakeHierarchyFolder([CanBeNull] HierarchyFolder hierarchyFolder) { // If this hierarchy folder has already been destroyed we should abort. if (hierarchyFolder == null) { return; } destroying.Remove(hierarchyFolder); HierarchyFolderUtility.UnmakeHierarchyFolder(hierarchyFolder.gameObject, hierarchyFolder); }
private void OnHierarchyFolderDetectedOnAPrefabAndNotAllowed(HierarchyFolder hierarchyFolder, bool isInstance) { // Prevent warning message being logged multiple times. if (hierarchyFolder == null || !destroying.Add(hierarchyFolder)) { return; } if (isInstance) { Debug.LogWarning(HierarchyFolderMessages.PrefabInstanceNotAllowed, hierarchyFolder.gameObject); } else { Debug.LogWarning(HierarchyFolderMessages.PrefabNotAllowed, hierarchyFolder.gameObject); } TurnIntoNormalGameObject(hierarchyFolder); }
private void Register(HierarchyFolder hierarchyFolder) { if (hierarchyFolder == null) { #if DEV_MODE Debug.LogWarning("HierarchyFolderController.Register called with null hierarchy folder."); #endif return; } if (hierarchyFolders.Contains(hierarchyFolder)) { return; } hierarchyFolders.Add(hierarchyFolder); #if DEV_MODE && DEBUG_REGISTER Debug.Log("Register \"" + hierarchyFolder.name + "\"\nTotal Count: " + hierarchyFolders.Count, hierarchyFolder); #endif }
internal void OnHierarchyChangedShared(HierarchyFolder hierarchyFolder) { if (HierarchyFolderUtility.HasSupernumeraryComponents(hierarchyFolder)) { // Prevent warning message being logged multiple times. if (!destroying.Add(hierarchyFolder)) { return; } Debug.LogWarning("Hierarchy Folder \"" + hierarchyFolder.name + "\" contained extraneous components.\nThis is not supported since Hierarchy Folders are stripped from builds. Converting into a normal GameObject now.", hierarchyFolder.gameObject); #if DEV_MODE foreach (var component in hierarchyFolder.gameObject.GetComponents <Component>()) { Debug.Log(component.GetType().Name); } #endif TurnIntoNormalGameObject(hierarchyFolder); } HierarchyFolderUtility.ResetTransformStateWithoutAffectingChildren(hierarchyFolder.transform); }
private void ApplyNamingPattern(HierarchyFolder hierarchyFolder) { var preferences = HierarchyFolderPreferences.Get(); if (!preferences.enableNamingRules) { return; } var gameObject = hierarchyFolder.gameObject; string setName = gameObject.name; bool possiblyChanged = false; if (preferences.forceNamesUpperCase) { setName = setName.ToUpper(); possiblyChanged = true; } string prefix = preferences.namePrefix; if (!setName.StartsWith(prefix, StringComparison.Ordinal)) { possiblyChanged = true; if (setName.StartsWith(preferences.previousNamePrefix, StringComparison.Ordinal)) { setName = setName.Substring(preferences.previousNamePrefix.Length); } for (int c = prefix.Length - 1; c >= 0 && !setName.StartsWith(prefix, StringComparison.Ordinal); c--) { setName = prefix[c] + setName; } } string suffix = preferences.nameSuffix; if (!setName.EndsWith(suffix, StringComparison.Ordinal)) { possiblyChanged = true; // Handle situation where a hierarchy folder has been duplicated and a string like "(1)" // has been added to the end of the name. if (setName.EndsWith(")", StringComparison.Ordinal)) { int openParenthesis = setName.LastIndexOf(" (", StringComparison.Ordinal); if (openParenthesis != -1) { string ending = setName.Substring(openParenthesis); if (ending.Length <= 5 && setName.EndsWith(suffix + ending, StringComparison.Ordinal)) { int from = openParenthesis + 2; int to = setName.Length - 1; string nthString = setName.Substring(from, to - from); int nthInt; if (int.TryParse(nthString, out nthInt)) { setName = setName.Substring(0, openParenthesis - suffix.Length) + suffix; } } } } if (setName.EndsWith(preferences.previousNameSuffix, StringComparison.Ordinal)) { setName = setName.Substring(0, setName.Length - preferences.previousNameSuffix.Length); } for (int c = 0, count = suffix.Length; c < count && !setName.EndsWith(suffix, StringComparison.Ordinal); c++) { setName += suffix[c]; } } if (possiblyChanged && !string.Equals(setName, gameObject.name)) { gameObject.name = setName; } }
private void TurnIntoNormalGameObject(HierarchyFolder hierarchyFolder) { // Can help avoid NullReferenceExceptions via hierarchyChanged callback // by adding a delay between the unsubscribing and the destroying of the HierarchyFolder component EditorApplication.delayCall += () => UnmakeHierarchyFolder(hierarchyFolder); }
private static int CompareHierarchyDepth([NotNull] HierarchyFolder x, [NotNull] HierarchyFolder y) { return(GetDepth(x).CompareTo(GetDepth(y))); }
private static bool IsNull(HierarchyFolder hierarchyFolder) { return(hierarchyFolder == null); }