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);
        }
예제 #2
0
        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);
        }
예제 #11
0
        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);
 }