public void ProcessComponent(Component component, Type componentType)
        {
            if (!enabled)
            {
                return;
            }

            existingData = null;
            newHash      = 0;

            if (!uniqueTypes.TryGetValue(componentType, out existingData))
            {
                var newData = new List <ComponentDuplicateInfo>();
                newData.Add(new ComponentDuplicateInfo(component));
                uniqueTypes.Add(componentType, newData);
            }
            else
            {
                foreach (var duplicateInfo in existingData)
                {
                    if (duplicateInfo.hash == 0)
                    {
                        var initialInfo            = new SerializedObjectTraverseInfo(duplicateInfo.reference);
                        var duplicateInfoInClosure = duplicateInfo;
                        CSTraverseTools.TraverseObjectProperties(initialInfo, (info, property) =>
                        {
                            duplicateInfoInClosure.hash += CSEditorTools.GetPropertyHash(property);
                        });
                    }
                }

                existingData.Add(new ComponentDuplicateInfo(component));
            }
        }
Exemple #2
0
        private void DrawStatsBody()
        {
            using (new GUILayout.HorizontalScope(UIHelpers.panelWithBackground))
            {
                GUILayout.Space(10);
                using (new GUILayout.VerticalScope())
                {
                    GUILayout.Space(5);
                    if (resultsStats == null)
                    {
                        GUILayout.Label("N/A");
                    }
                    else
                    {
                        GUILayout.Space(5);
                        GUILayout.Label("Physical size");
                        UIHelpers.Separator();
                        GUILayout.Label("Total found: " + CSEditorTools.FormatBytes(resultsStats.totalSize));
                        GUILayout.Label("Selected: " + CSEditorTools.FormatBytes(resultsStats.selectedSize));
                    }

                    GUILayout.Space(5);
                }
                GUILayout.Space(10);
            }
        }
Exemple #3
0
        protected GameObjectIssueRecord(IssueKind kind, RecordLocation location, string path, GameObject gameObject) : base(kind, location, path)
        {
            var transform = gameObject.transform;

            transformPath = CSEditorTools.GetFullTransformPath(transform);

            if (kind != IssueKind.MissingPrefab)
            {
                objectId = CSObjectTools.GetUniqueObjectId(gameObject);
            }
        }
 protected override void ConstructBody(StringBuilder text)
 {
     text.Append("<b>Path:</b> ").Append(beautyPath);
     if (size > 0)
     {
         text.AppendLine().Append("<b>Size:</b> ").Append(CSEditorTools.FormatBytes(size));
     }
     if (type == RecordType.UnreferencedAsset)
     {
         text.AppendLine().Append("<b>Full Type:</b> ").Append(assetType.FullName);
     }
 }
Exemple #5
0
        /// <summary>
        /// Starts garbage search, cleans what was found with optional confirmation and
        /// generates report to let you know what were cleaned up.
        /// </summary>
        /// <param name="showConfirmation">Enables or disables confirmation dialog about cleaning up found stuff.</param>
        /// <returns>Project Cleaner report about removed items.</returns>
        /// %Maintainer window is not shown.
        /// <br/>Useful when you wish to integrate %Maintainer in your build pipeline.
        public static string SearchAndCleanAndReport(bool showConfirmation = true)
        {
            var foundGarbage   = StartSearch(false);
            var cleanedGarbage = StartClean(foundGarbage, false, showConfirmation);

            var header = "Total cleaned bytes: " + CSEditorTools.FormatBytes(cleanedBytes);

            header += "\nFollowing items were cleaned up:";

            // ReSharper disable once CoVariantArrayConversion
            return(ReportsBuilder.GenerateReport(ModuleName, cleanedGarbage, header));
        }
        private static bool ProcessSelectedScenes(List <IssueRecord> issues)
        {
            bool result = true;

            currentPhase++;

            for (int i = 0; i < scenesCount; i++)
            {
                string scenePath = scenesPaths[i];
                string sceneName = Path.GetFileNameWithoutExtension(scenePath);

                if (EditorUtility.DisplayCancelableProgressBar(string.Format(PROGRESS_CAPTION, currentPhase, phasesCount, i + 1, scenesCount), string.Format("Opening scene: " + Path.GetFileNameWithoutExtension(scenePath)), (float)i / scenesCount))
                {
                    result = false;
                    break;
                }

                if (CSSceneTools.GetCurrentScenePath() != scenePath)
                {
                    CSSceneTools.OpenScene(scenePath);
                }
#if UNITY_5_3_PLUS
                // if we're scanning currently opened scene and going to scan more scenes,
                // we need to close all additional scenes to avoid duplicates
                else if (EditorSceneManager.loadedSceneCount > 1 && scenesCount > 1)
                {
                    CSSceneTools.CloseAllScenesButActive();
                }
#endif

                GameObject[] gameObjects  = CSEditorTools.GetAllSuitableGameObjectsInCurrentScene();
                int          objectsCount = gameObjects.Length;

                for (int j = 0; j < objectsCount; j++)
                {
                    if (EditorUtility.DisplayCancelableProgressBar(string.Format(PROGRESS_CAPTION, currentPhase, phasesCount, i + 1, scenesCount), string.Format("Processing scene: {0} ... {1}%", sceneName, j * 100 / objectsCount), (float)i / scenesCount))
                    {
                        result = false;
                        break;
                    }

                    CheckObjectForIssues(issues, scenePath, gameObjects[j], true);
                }

                if (!result)
                {
                    break;
                }
            }

            return(result);
        }
        protected GameObjectIssueRecord(RecordType type, RecordLocation location, string path, GameObject gameObject) : base(type, location)
        {
            this.path      = path;
            gameObjectPath = CSEditorTools.GetFullTransformPath(gameObject.transform);
            objectId       = CSObjectTools.GetLocalIdentifierInFileForObject(gameObject);

#if UNITY_5_3_PLUS
            if (location == RecordLocation.Scene)
            {
                this.path = gameObject.scene.path;
            }
#endif
        }
        public void Show()
        {
            GameObject[] allObjects;

            if (location == RecordLocation.Scene)
            {
                if (CSSceneTools.GetCurrentScenePath() != path)
                {
                    if (!CSSceneTools.SaveCurrentSceneIfUserWantsTo())
                    {
                        return;
                    }
                    CSSceneTools.OpenScene(path);
                }

                allObjects = CSEditorTools.GetAllSuitableGameObjectsInCurrentScene();
                CSEditorTools.PingObjectDelayed(AssetDatabase.LoadAssetAtPath(path, typeof(Object)));
            }
            else
            {
                List <GameObject> prefabs = new List <GameObject>();
                CSEditorTools.GetAllSuitableGameObjectsInPrefabAssets(prefabs);
                allObjects = prefabs.ToArray();
            }

            GameObject go = FindObjectInCollection(allObjects);

            if (go != null)
            {
                if (location == RecordLocation.Scene)
                {
                    Selection.activeTransform = go.transform;
                }
                else
                {
                    Selection.activeGameObject = go;

                    if (gameObjectPath.Split('/').Length > 2)
                    {
                        CSEditorTools.PingObjectDelayed(AssetDatabase.LoadAssetAtPath(path, typeof(Object)));
                    }
                }
            }
            else
            {
                MaintainerWindow.ShowNotification("Can't find object " + gameObjectPath);
            }
        }
Exemple #9
0
        private static bool ScanSceneFiles(List <CleanerRecord> results, bool showProgress = true)
        {
            bool canceled = false;

            currentPhase++;

            string[] scenesPaths = CSEditorTools.FindAssetsFiltered("t:Scene", MaintainerSettings.Cleaner.pathIgnores);

            int scenesCount = scenesPaths.Length;

            for (int i = 0; i < scenesCount; i++)
            {
                if (showProgress && EditorUtility.DisplayCancelableProgressBar(string.Format(PROGRESS_CAPTION, currentPhase, phasesCount, i + 1, scenesCount), "Scanning scene files...", (float)i / scenesCount))
                {
                    canceled = true;
                    break;
                }

                string scenePath = scenesPaths[i];

                if (CSSceneTools.GetCurrentScenePath() != scenePath)
                {
                    CSSceneTools.OpenScene(scenePath);
                }

#if UNITY_5_3_PLUS
                // if we're scanning currently opened scene and going to scan more scenes,
                // we need to close all additional scenes to avoid duplicates
                else if (EditorSceneManager.loadedSceneCount > 1 && scenesCount > 1)
                {
                    CSSceneTools.CloseAllScenesButActive();
                }
#endif
                int objectsInScene = 0;

                GameObject[] gameObjects = CSEditorTools.GetAllSuitableGameObjectsInCurrentScene();
                objectsInScene = gameObjects.Length;

                if (objectsInScene == 0)
                {
                    results.Add(AssetRecord.Create(RecordType.EmptyScene, scenePath));
                }
            }

            return(!canceled);
        }
Exemple #10
0
        private GameObject GetGameObjectWithThisIssue()
        {
            GameObject[] allObjects;

            if (location == RecordLocation.Scene)
            {
                allObjects = CSEditorTools.GetAllSuitableGameObjectsInCurrentScene();
            }
            else
            {
                List <GameObject> prefabs = new List <GameObject>();
                CSEditorTools.GetAllSuitableGameObjectsInPrefabAssets(prefabs);
                allObjects = prefabs.ToArray();
            }

            return(FindObjectInCollection(allObjects));
        }
        private static void ShowItem(ReferencesTreeViewItem <T> item)
        {
            var assetPath = item.data.assetPath;

            if (item.data.assetSettingsKind == AssetSettingsKind.NotSettings)
            {
                if (!CSSelectionTools.RevealAndSelectFileAsset(assetPath))
                {
                    MaintainerWindow.ShowNotification("Can't show it properly");
                }
            }
            else
            {
                if (!CSEditorTools.RevealInSettings(item.data.assetSettingsKind, assetPath))
                {
                    MaintainerWindow.ShowNotification("Can't show it properly");
                }
            }
        }
        private GameObject FindObjectInCollection(IEnumerable <GameObject> allObjects)
        {
            GameObject candidate = null;

            foreach (GameObject gameObject in allObjects)
            {
                if (CSEditorTools.GetFullTransformPath(gameObject.transform) != gameObjectPath)
                {
                    continue;
                }

                candidate = gameObject;
                if (objectId == CSObjectTools.GetLocalIdentifierInFileForObject(candidate))
                {
                    break;
                }
            }
            return(candidate);
        }
Exemple #13
0
        protected override void ShowItem(TreeViewItem clickedItem)
        {
            var item      = (ProjectReferencesTreeViewItem <T>)clickedItem;
            var assetPath = item.data.assetPath;

            if (item.data.assetSettingsKind == AssetSettingsKind.NotSettings)
            {
                if (!CSSelectionTools.RevealAndSelectFileAsset(assetPath))
                {
                    MaintainerWindow.ShowNotification("Can't show it properly");
                }
            }
            else
            {
                if (!CSEditorTools.RevealInSettings(item.data.assetSettingsKind, assetPath))
                {
                    MaintainerWindow.ShowNotification("Can't show it properly");
                }
            }
        }
        protected override void ConstructBody(StringBuilder text)
        {
            text.Append(location == RecordLocation.Scene ? "<b>Scene:</b> " : "<b>Prefab:</b> ");

            string nicePath = path == "" ? "Untitled (current scene)" : CSEditorTools.NicifyAssetPath(path);

            text.Append(nicePath);

            if (!string.IsNullOrEmpty(gameObjectPath))
            {
                text.Append("\n<b>Game Object:</b> ").Append(gameObjectPath);
            }
            if (!string.IsNullOrEmpty(component))
            {
                text.Append("\n<b>Component:</b> ").Append(component);
            }
            if (!string.IsNullOrEmpty(property))
            {
                text.Append("\n<b>Property:</b> ").Append(property);
            }
        }
Exemple #15
0
        // ----------------------------------------------------------------------------
        // fix missing component
        // ----------------------------------------------------------------------------

        private static void FixMissingComponents(GameObjectIssueRecord issue, GameObject go)
        {
            CSObjectTools.SelectGameObject(go, issue.location);

            ActiveEditorTracker tracker = CSEditorTools.GetActiveEditorTrackerForSelectedObject();

            tracker.RebuildIfNecessary();

            bool touched = false;

            Editor[] activeEditors = tracker.activeEditors;
            for (int i = activeEditors.Length - 1; i >= 0; i--)
            {
                Editor editor = activeEditors[i];
                if (CSObjectTools.GetLocalIdentifierInFileForObject(editor.serializedObject.targetObject) == issue.componentId)
                {
                    Object.DestroyImmediate(editor.target, true);
                    touched = true;
                }
            }

            if (touched)
            {
#if UNITY_5_0_PLUS
                if (issue.location == RecordLocation.Scene)
                {
                    CSSceneTools.MarkSceneDirty();
                }
                else
                {
                    EditorUtility.SetDirty(go);
                }
#else
                EditorUtility.SetDirty(go);
#endif
            }

            //CSObjectTools.SelectGameObject(null, issue.location);
        }
        private static void CheckObjectForIssues(List <IssueRecord> issues, string path, GameObject go, bool checkingScene)
        {
            RecordLocation location = checkingScene ? RecordLocation.Scene : RecordLocation.Prefab;

            // ----------------------------------------------------------------------------
            // looking for object-level issues
            // ----------------------------------------------------------------------------

            if (!MaintainerSettings.Issues.touchInactiveGameObjects)
            {
                if (checkingScene)
                {
                    if (!go.activeInHierarchy)
                    {
                        return;
                    }
                }
                else
                {
                    if (!go.activeSelf)
                    {
                        return;
                    }
                }
            }

            // ----------------------------------------------------------------------------
            // checking all components for ignores
            // ----------------------------------------------------------------------------

            bool checkForIgnores      = (MaintainerSettings.Issues.componentIgnores != null && MaintainerSettings.Issues.componentIgnores.Length > 0);
            bool skipEmptyMeshFilter  = false;
            bool skipEmptyAudioSource = false;

            Component[] allComponents      = go.GetComponents <Component>();
            int         allComponentsCount = allComponents.Length;

            List <Component> components           = new List <Component>(allComponentsCount);
            List <Type>      componentsTypes      = new List <Type>(allComponentsCount);
            List <string>    componentsNames      = new List <string>(allComponentsCount);
            List <string>    componentsFullNames  = new List <string>(allComponentsCount);
            List <string>    componentsNamespaces = new List <string>(allComponentsCount);

            int componentsCount = 0;

            for (int i = 0; i < allComponentsCount; i++)
            {
                Component component = allComponents[i];

                if (component == null)
                {
                    if (MaintainerSettings.Issues.missingComponents)
                    {
                        issues.Add(GameObjectIssueRecord.Create(RecordType.MissingComponent, location, path, go));
                    }
                    continue;
                }

                Type   componentType      = component.GetType();
                string componentName      = componentType.Name;
                string componentFullName  = componentType.FullName;
                string componentNamespace = componentType.Namespace;

                /*
                 * checking object for the components which may affect
                 * other components and produce false positives
                 */

                // allowing empty mesh filters for the objects with attached TextMeshPro and 2D Toolkit components.
                if (!skipEmptyMeshFilter)
                {
                    skipEmptyMeshFilter = (componentFullName == "TMPro.TextMeshPro") || componentName.StartsWith("tk2d");
                }

                // allowing empty AudioSources for the objects with attached standard FirstPersonController.
                if (!skipEmptyAudioSource)
                {
                    skipEmptyAudioSource = componentFullName == "UnityStandardAssets.Characters.FirstPerson.FirstPersonController";
                }

                // skipping disabled components
                if (!MaintainerSettings.Issues.touchDisabledComponents)
                {
                    if (EditorUtility.GetObjectEnabled(component) == 0)
                    {
                        continue;
                    }
                }

                // skipping ignored components
                if (checkForIgnores)
                {
                    if (Array.IndexOf(MaintainerSettings.Issues.componentIgnores, componentName) != -1)
                    {
                        continue;
                    }
                }

                components.Add(component);
                componentsTypes.Add(componentType);
                componentsNames.Add(componentName);
                componentsFullNames.Add(componentFullName);
                componentsNamespaces.Add(componentNamespace);
                componentsCount++;
            }

            // ----------------------------------------------------------------------------
            // checking stuff related to the prefabs in scenes
            // ----------------------------------------------------------------------------

            if (checkingScene)
            {
                PrefabType prefabType = PrefabUtility.GetPrefabType(go);

                if (prefabType != PrefabType.None)
                {
                    /* checking if we're inside of nested prefab with same type as root,
                     * allows to skip detections of missed and disconnected prefabs children */

                    GameObject rootPrefab            = PrefabUtility.FindRootGameObjectWithSameParentPrefab(go);
                    bool       rootPrefabHasSameType = false;
                    if (rootPrefab != go)
                    {
                        PrefabType rootPrefabType = PrefabUtility.GetPrefabType(rootPrefab);
                        if (rootPrefabType == prefabType)
                        {
                            rootPrefabHasSameType = true;
                        }
                    }

                    if (prefabType == PrefabType.MissingPrefabInstance)
                    {
                        if (MaintainerSettings.Issues.missingPrefabs && !rootPrefabHasSameType)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.MissingPrefab, location, path, go));
                        }
                    }
                    else if (prefabType == PrefabType.DisconnectedPrefabInstance ||
                             prefabType == PrefabType.DisconnectedModelPrefabInstance)
                    {
                        if (MaintainerSettings.Issues.disconnectedPrefabs && !rootPrefabHasSameType)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.DisconnectedPrefab, location, path, go));
                        }
                    }

                    /* checking if this game object is actually prefab instance
                     * without any changes, so we can skip it if we have assets search enabled */

                    if (prefabType != PrefabType.DisconnectedPrefabInstance &&
                        prefabType != PrefabType.DisconnectedModelPrefabInstance &&
                        prefabType != PrefabType.MissingPrefabInstance && MaintainerSettings.Issues.lookInAssets)
                    {
                        bool skipThisPrefabInstance = true;

                        // we shouldn't skip object if it's nested deeper 2nd level
                        if (CSEditorTools.GetDepthInHierarchy(go.transform, rootPrefab.transform) >= 2)
                        {
                            skipThisPrefabInstance = false;
                        }
                        else
                        {
                            PropertyModification[] modifications = PrefabUtility.GetPropertyModifications(go);
                            foreach (PropertyModification modification in modifications)
                            {
                                Object target = modification.target;

                                if (target is Transform)
                                {
                                    continue;
                                }

                                skipThisPrefabInstance = false;
                                break;
                            }
                        }
                        if (skipThisPrefabInstance)
                        {
                            return;
                        }
                    }
                }
            }

            if (MaintainerSettings.Issues.undefinedTags)
            {
                bool undefinedTag = false;
                try
                {
                    if (string.IsNullOrEmpty(go.tag))
                    {
                        undefinedTag = true;
                    }
                }
                catch (UnityException e)
                {
                    if (e.Message.Contains("undefined tag"))
                    {
                        undefinedTag = true;
                    }
                    else
                    {
                        Debug.LogError(Maintainer.LOG_PREFIX + "Unknown error while checking tag of the " + go.name + "\n" + e);
                    }
                }

                if (undefinedTag)
                {
                    issues.Add(GameObjectIssueRecord.Create(RecordType.UndefinedTag, location, path, go));
                }
            }

            if (MaintainerSettings.Issues.unnamedLayers)
            {
                int layerIndex = go.layer;
                if (string.IsNullOrEmpty(LayerMask.LayerToName(layerIndex)))
                {
                    GameObjectIssueRecord issue = GameObjectIssueRecord.Create(RecordType.UnnamedLayer, location, path, go);
                    issue.headerExtra = "(index: " + layerIndex + ")";
                    issues.Add(issue);
                }
            }

            Dictionary <Type, int> uniqueTypes = null;
            List <int>             similarComponentsIndexes = null;

            TerrainData terrainTerrainData         = null;
            TerrainData terrainColliderTerrainData = null;
            bool        terrainChecked             = false;
            bool        terrainColliderChecked     = false;

            // ----------------------------------------------------------------------------
            // looking for component-level issues
            // ----------------------------------------------------------------------------

            for (int i = 0; i < componentsCount; i++)
            {
                Component component     = components[i];
                Type      componentType = componentsTypes[i];
                string    componentName = componentsNames[i];
                //string componentFullName = componentsFullNames[i];
                string componentNamespace = componentsNamespaces[i];

                if (component is Transform)
                {
                    if (MaintainerSettings.Issues.hugePositions)
                    {
                        Vector3 position = (component as Transform).position;

                        if (Math.Abs(position.x) > 100000f || Math.Abs(position.y) > 100000f || Math.Abs(position.z) > 100000f)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.HugePosition, location, path, go, component, componentType, componentName, "Position"));
                        }
                    }
                    continue;
                }

                if (MaintainerSettings.Issues.duplicateComponents &&
                    (componentNamespace != "Fabric"))
                {
                    // initializing dictionary and list on first usage
                    if (uniqueTypes == null)
                    {
                        uniqueTypes = new Dictionary <Type, int>(componentsCount);
                    }
                    if (similarComponentsIndexes == null)
                    {
                        similarComponentsIndexes = new List <int>(componentsCount);
                    }

                    // checking if current component type already met before
                    if (uniqueTypes.ContainsKey(componentType))
                    {
                        int uniqueTypeIndex = uniqueTypes[componentType];

                        // checking if initially met component index already in indexes list
                        // since we need to compare all duplicate candidates against initial component
                        if (!similarComponentsIndexes.Contains(uniqueTypeIndex))
                        {
                            similarComponentsIndexes.Add(uniqueTypeIndex);
                        }

                        // adding current component index to the indexes list
                        similarComponentsIndexes.Add(i);
                    }
                    else
                    {
                        uniqueTypes.Add(componentType, i);
                    }
                }

                if (component is MeshCollider)
                {
                    if (MaintainerSettings.Issues.emptyMeshColliders)
                    {
                        if ((component as MeshCollider).sharedMesh == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyMeshCollider, location, path, go, component, componentType, componentName));
                        }
                    }
                }
                else if (component is MeshFilter)
                {
                    if (MaintainerSettings.Issues.emptyMeshFilters && !skipEmptyMeshFilter)
                    {
                        if ((component as MeshFilter).sharedMesh == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyMeshFilter, location, path, go, component, componentType, componentName));
                        }
                    }
                }
                else if (component is Renderer)
                {
                    if (MaintainerSettings.Issues.emptyRenderers)
                    {
                        if ((component as Renderer).sharedMaterial == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyRenderer, location, path, go, component, componentType, componentName));
                        }
                    }

                    if (component is SpriteRenderer)
                    {
                        if (MaintainerSettings.Issues.emptySpriteRenderers)
                        {
                            if ((component as SpriteRenderer).sprite == null)
                            {
                                issues.Add(GameObjectIssueRecord.Create(RecordType.EmptySpriteRenderer, location, path, go, component, componentType, componentName));
                            }
                        }
                    }
                }
                else if (component is Animation)
                {
                    if (MaintainerSettings.Issues.emptyAnimations)
                    {
                        if ((component as Animation).GetClipCount() <= 0 && (component as Animation).clip == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyAnimation, location, path, go, component, componentType, componentName));
                        }
                    }
                }
                else if (component is Terrain)
                {
                    if (MaintainerSettings.Issues.inconsistentTerrainData)
                    {
                        terrainTerrainData = (component as Terrain).terrainData;
                        terrainChecked     = true;
                    }
                }
                else if (component is TerrainCollider)
                {
                    if (MaintainerSettings.Issues.inconsistentTerrainData)
                    {
                        terrainColliderTerrainData = (component as TerrainCollider).terrainData;
                        terrainColliderChecked     = true;
                    }

                    if (MaintainerSettings.Issues.emptyTerrainCollider)
                    {
                        if ((component as TerrainCollider).terrainData == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyTerrainCollider, location, path, go, component, componentType, componentName));
                        }
                    }
                }
                else if (component is AudioSource)
                {
                    if (MaintainerSettings.Issues.emptyAudioSource && !skipEmptyAudioSource)
                    {
                        if ((component as AudioSource).clip == null)
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.EmptyAudioSource, location, path, go, component, componentType, componentName));
                        }
                    }
                }

                // ----------------------------------------------------------------------------
                // looping through the component's SerializedProperties via SerializedObject
                // ----------------------------------------------------------------------------

                Dictionary <string, int> emptyArrayItems = new Dictionary <string, int>();
                SerializedObject         so = new SerializedObject(component);
                SerializedProperty       sp = so.GetIterator();

                while (sp.NextVisible(true))
                {
                    string fullPropertyPath = sp.propertyPath;

                    bool isArrayItem = fullPropertyPath.EndsWith("]", StringComparison.Ordinal);

                    if (MaintainerSettings.Issues.missingReferences)
                    {
                        if (sp.propertyType == SerializedPropertyType.ObjectReference)
                        {
                            if (sp.objectReferenceValue == null && sp.objectReferenceInstanceIDValue != 0)
                            {
                                string propertyName = isArrayItem ? GetArrayItemNameAndIndex(fullPropertyPath) : sp.name;
                                issues.Add(GameObjectIssueRecord.Create(RecordType.MissingReference, location, path, go, component, componentType, componentName, propertyName));
                            }
                        }
                    }

                    if (checkingScene || !MaintainerSettings.Issues.skipEmptyArrayItemsOnPrefabs)
                    {
                        // skipping SpriteRenderer as it has hidden array with materials of size 1
                        if (MaintainerSettings.Issues.emptyArrayItems && isArrayItem)
                        {
                            // ignoring components where empty array items is a normal behavior
                            if (!(component is SpriteRenderer) && !componentName.StartsWith("TextMeshPro"))
                            {
                                if (sp.propertyType == SerializedPropertyType.ObjectReference &&
                                    sp.objectReferenceValue == null &&
                                    sp.objectReferenceInstanceIDValue == 0)
                                {
                                    string arrayName = GetArrayItemName(fullPropertyPath);

                                    // ignoring TextMeshPro's FontAssetArrays with 16 empty items inside
                                    if (!emptyArrayItems.ContainsKey(arrayName))
                                    {
                                        emptyArrayItems.Add(arrayName, 0);
                                    }
                                    emptyArrayItems[arrayName]++;
                                }
                            }
                        }
                    }

                    /*else
                     * {
                     *      continue;
                     * }*/
                }

                if (MaintainerSettings.Issues.emptyArrayItems)
                {
                    foreach (var item in emptyArrayItems.Keys)
                    {
                        GameObjectIssueRecord issueRecord = GameObjectIssueRecord.Create(RecordType.EmptyArrayItem, location, path, go, component, componentType, componentName, item);
                        issueRecord.headerFormatArgument = emptyArrayItems[item].ToString();
                        issues.Add(issueRecord);
                    }
                }
            }

            if (MaintainerSettings.Issues.inconsistentTerrainData &&
                terrainColliderTerrainData != terrainTerrainData &&
                terrainChecked && terrainColliderChecked)
            {
                issues.Add(GameObjectIssueRecord.Create(RecordType.InconsistentTerrainData, location, path, go));
            }

            if (MaintainerSettings.Issues.duplicateComponents)
            {
                if (similarComponentsIndexes != null && similarComponentsIndexes.Count > 0)
                {
                    int         similarComponentsCount  = similarComponentsIndexes.Count;
                    List <long> similarComponentsHashes = new List <long>(similarComponentsCount);

                    for (int i = 0; i < similarComponentsCount; i++)
                    {
                        int       componentIndex = similarComponentsIndexes[i];
                        Component component      = components[componentIndex];

                        long componentHash = 0;

                        if (MaintainerSettings.Issues.duplicateComponentsPrecise)
                        {
                            SerializedObject   so = new SerializedObject(component);
                            SerializedProperty sp = so.GetIterator();
                            while (sp.NextVisible(true))
                            {
                                componentHash += CSEditorTools.GetPropertyHash(sp);
                            }
                        }

                        similarComponentsHashes.Add(componentHash);
                    }

                    List <long> distinctItems = new List <long>(similarComponentsCount);

                    for (int i = 0; i < similarComponentsCount; i++)
                    {
                        int componentIndex = similarComponentsIndexes[i];

                        if (distinctItems.Contains(similarComponentsHashes[i]))
                        {
                            issues.Add(GameObjectIssueRecord.Create(RecordType.DuplicateComponent, location, path, go, components[componentIndex], componentsTypes[componentIndex], componentsNames[componentIndex]));
                        }
                        else
                        {
                            distinctItems.Add(similarComponentsHashes[i]);
                        }
                    }
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Starts clean of the garbage found with StartSearch() method.
        /// </summary>
        /// <param name="recordsToClean">Pass records you wish to clean here or leave null to let it load last search results.</param>
        /// <param name="showResults">Shows results in the %Maintainer window if true.</param>
        /// <param name="showConfirmation">Shows confirmation dialog before performing cleanup if true.</param>
        /// <returns>Array of CleanRecords which were cleaned up.</returns>
        public static CleanerRecord[] StartClean(CleanerRecord[] recordsToClean = null, bool showResults = true, bool showConfirmation = true)
        {
            var records = recordsToClean;

            if (records == null)
            {
                records = SearchResultsStorage.CleanerSearchResults;
            }

            if (records.Length == 0)
            {
                return(null);
            }

            cleanedBytes = 0;
            itemsToClean = 0;

            foreach (var record in records)
            {
                if (record.selected)
                {
                    itemsToClean++;
                }
            }

            if (itemsToClean == 0)
            {
                EditorUtility.DisplayDialog(ModuleName, "Please select items to clean up!", "Ok");
                return(null);
            }

            if (!showConfirmation || itemsToClean == 1 || EditorUtility.DisplayDialog("Confirmation", "Do you really wish to delete " + itemsToClean + " items?\n" + Maintainer.DataLossWarning, "Go for it!", "Cancel"))
            {
                var sw = System.Diagnostics.Stopwatch.StartNew();

                var cleanCanceled = CleanRecords(records);

                var cleanedRecords    = new List <CleanerRecord>(records.Length);
                var notCleanedRecords = new List <CleanerRecord>(records.Length);

                foreach (var record in records)
                {
                    if (record.cleaned)
                    {
                        cleanedRecords.Add(record);
                    }
                    else
                    {
                        notCleanedRecords.Add(record);
                    }
                }

                records = notCleanedRecords.ToArray();

                sw.Stop();

                EditorUtility.ClearProgressBar();

                if (!cleanCanceled)
                {
                    Debug.Log(Maintainer.LogPrefix + ModuleName + " results: " + cleanedRecords.Count +
                              " items (" + CSEditorTools.FormatBytes(cleanedBytes) + " in size) cleaned in " + sw.Elapsed.TotalSeconds.ToString("0.000") +
                              " seconds.");
                }
                else
                {
                    Debug.Log(Maintainer.LogPrefix + "Deletion was canceled by user!");
                }

                SearchResultsStorage.CleanerSearchResults = records;
                if (showResults)
                {
                    MaintainerWindow.ShowCleaner();
                }

                return(cleanedRecords.ToArray());
            }

            return(null);
        }
        private static void CheckBuildSettings(List <IssueRecord> issues)
        {
            if (MaintainerSettings.Issues.duplicateScenesInBuild)
            {
                string[] scenesForBuild = GetEnabledScenesInBuild();
                string[] duplicates     = CSArrayTools.FindDuplicatesInArray(scenesForBuild);

                foreach (var duplicate in duplicates)
                {
                    issues.Add(BuildSettingsIssueRecord.Create(RecordType.DuplicateScenesInBuild,
                                                               "<b>Duplicate scene:</b> " + CSEditorTools.NicifyAssetPath(duplicate)));
                }
            }
        }
Exemple #19
0
 protected override string GetReportHeader()
 {
     return(resultsStats != null ? "Total found garbage size: " + CSEditorTools.FormatBytes(resultsStats.totalSize) : null);
 }
Exemple #20
0
        public static ReferencesTreeElement BuildTreeBranch(AssetInfo referencedAsset, int depth, int id, List <ReferencesTreeElement> results)
        {
            // excludes assets without references if necessary and excludes assets which were ignored
            if (AssetIsFilteredOut(referencedAsset, depth))
            {
                return(null);
            }

            var    assetPath = referencedAsset.Path;
            var    assetType = referencedAsset.Type;
            string assetTypeName;

            if (referencedAsset.SettingsKind == AssetSettingsKind.NotSettings)
            {
                assetTypeName = assetType != null && !string.IsNullOrEmpty(assetType.Name) ? assetType.Name : "Unknown type";
            }
            else
            {
                assetTypeName = "Settings Asset";
            }

            var element = new ReferencesTreeElement
            {
                id                 = id + results.Count,
                name               = CSPathTools.NicifyAssetPath(referencedAsset.Path, referencedAsset.Kind),
                assetPath          = assetPath,
                assetTypeName      = assetTypeName,
                assetSize          = referencedAsset.Size,
                assetSizeFormatted = CSEditorTools.FormatBytes(referencedAsset.Size),
                assetIsTexture     = assetType != null && (assetType.BaseType == CSReflectionTools.textureType),
                assetSettingsKind  = referencedAsset.SettingsKind,
                isReferenced       = referencedAsset.referencedAtInfoList != null && referencedAsset.referencedAtInfoList.Length > 0,
                depth              = depth
            };

            results.Add(element);

            var recursionId = CheckParentsForRecursion(element, results);

            if (recursionId > -1)
            {
                element.name       += " [RECURSION]";
                element.recursionId = recursionId;
                return(element);
            }

            if (referencedAsset.referencedAtInfoList.Length > 0)
            {
                foreach (var referencedAtInfo in referencedAsset.referencedAtInfoList)
                {
                    //if (CSFilterTools.IsValueMatchesAnyFilter(referencedAtInfo.assetInfo.Path, MaintainerSettings.References.pathIgnoresFilters)) continue;
                    if (referencedAtInfo.assetInfo.Kind == AssetKind.FromPackage)
                    {
                        continue;
                    }

                    var newDepth = depth + 1;

                    if (newDepth > 1)
                    {
                        continue;
                    }

                    var childElement = BuildTreeBranch(referencedAtInfo.assetInfo, newDepth, id, results);
                    if (childElement == null)
                    {
                        continue;
                    }

                    var referencedAtType = referencedAtInfo.assetInfo.Type;

                    if (referencedAtType == CSReflectionTools.gameObjectType ||
                        referencedAtType == CSReflectionTools.sceneAssetType ||
                        referencedAtType == CSReflectionTools.monoScriptType ||
                        referencedAtType == CSReflectionTools.monoBehaviourType ||
                        referencedAtType != null && referencedAtType.BaseType == CSReflectionTools.scriptableObjectType)
                    {
                        if (referencedAtInfo.entries != null)
                        {
                            childElement.referencingEntries = referencedAtInfo.entries;
                        }
                        else
                        {
                            var collectedData = ReferencesFinder.ConjunctionInfoList.FirstOrDefault(d => d.asset == referencedAtInfo.assetInfo);

                            if (collectedData == null)
                            {
                                collectedData = new AssetConjunctions();
                                ReferencesFinder.ConjunctionInfoList.Add(collectedData);
                                collectedData.asset = referencedAtInfo.assetInfo;
                            }

                            var tc = collectedData.conjunctions.FirstOrDefault(c => c.referencedAsset == referencedAsset);

                            if (tc == null)
                            {
                                tc = new TreeConjunction
                                {
                                    referencedAsset  = referencedAsset,
                                    referencedAtInfo = referencedAtInfo
                                };

                                collectedData.conjunctions.Add(tc);
                            }
                            tc.treeElements.Add(childElement);
                        }
                    }
                }
            }

            return(element);
        }
 public void ProcessProperty(UnityEditor.SerializedProperty property)
 {
     newHash += CSEditorTools.GetPropertyHash(property);
 }
Exemple #22
0
 public void Show()
 {
     CSEditorTools.RevealInSettings(SettingsKind);
 }
Exemple #23
0
        // -----------------------------------------------------------------------------
        // fix missing component
        // -----------------------------------------------------------------------------

        private static bool FixMissingComponents(GameObjectIssueRecord issue, GameObject go, bool alternative)
        {
            var touched = false;

            // TODO: re-check in Unity 2021
            // unfortunately RemoveMonoBehavioursWithMissingScript does not works correctly:
            // https://forum.unity.com/threads/remove-all-missing-components-in-prefabs.897761/
            // so it will be enabled back in later Unity versions

            /*var removedCount = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(go);
             * if (removedCount > 0)
             * {
             *      touched = true;
             * }*/

            if (!alternative)
            {
                CSObjectTools.SelectGameObject(go, issue.Location == RecordLocation.Scene);
            }

            var tracker = CSEditorTools.GetActiveEditorTrackerForSelectedObject();

            if (tracker == null)
            {
                Debug.LogError(Maintainer.ConstructError("Can't get active tracker."));
                return(false);
            }
            tracker.RebuildIfNecessary();

            var activeEditors = tracker.activeEditors;

            for (var i = activeEditors.Length - 1; i >= 0; i--)
            {
                var editor = activeEditors[i];
                if (editor.serializedObject.targetObject == null)
                {
                    Object.DestroyImmediate(editor.target, true);
                    touched = true;
                }
            }

            if (alternative)
            {
                return(touched);
            }

            if (!touched)
            {
                // missing script could be hidden with hide flags, so let's try select it directly and repeat
                var serializedObject = new SerializedObject(go);
                var componentsArray  = serializedObject.FindProperty("m_Component");
                if (componentsArray != null)
                {
                    for (var i = componentsArray.arraySize - 1; i >= 0; i--)
                    {
                        var componentPair   = componentsArray.GetArrayElementAtIndex(i);
                        var nestedComponent = componentPair.FindPropertyRelative("component");
                        if (nestedComponent != null)
                        {
                            if (MissingReferenceDetector.IsPropertyHasMissingReference(nestedComponent))
                            {
                                var instanceId = nestedComponent.objectReferenceInstanceIDValue;
                                if (instanceId == 0)
                                {
                                    var fileId = nestedComponent.FindPropertyRelative("m_FileID");
                                    if (fileId != null)
                                    {
                                        instanceId = fileId.intValue;
                                    }
                                }

                                Selection.instanceIDs = new [] { instanceId };
                                touched |= FixMissingComponents(issue, go, true);
                            }
                        }
                        else
                        {
                            Debug.LogError(Maintainer.LogPrefix + "Couldn't find component in component pair!");
                            break;
                        }
                    }

                    if (touched)
                    {
                        CSObjectTools.SelectGameObject(go, issue.Location == RecordLocation.Scene);
                    }
                }
                else
                {
                    Debug.LogError(Maintainer.LogPrefix + "Couldn't find components array!");
                }
            }

            if (touched)
            {
                if (issue.Location == RecordLocation.Scene)
                {
                    CSSceneTools.MarkSceneDirty();
                }
                else
                {
                    EditorUtility.SetDirty(go);
                }
            }

            return(touched);
        }
Exemple #24
0
        private static void ShowItem(ReferencesTreeViewItem <T> item, ReferencingEntryData referencingEntry = null)
        {
            var assetPath = item.data.assetPath;

            if (referencingEntry != null)
            {
                if (referencingEntry.location == Location.SceneLightingSettings || referencingEntry.location == Location.SceneNavigationSettings)
                {
                    var sceneOpenResult = CSSceneTools.OpenSceneWithSavePrompt(assetPath);
                    if (!sceneOpenResult.success)
                    {
                        Debug.LogError(Maintainer.ConstructError("Can't open scene " + assetPath));
                        MaintainerWindow.ShowNotification("Can't show it properly");
                        return;
                    }
                }

                switch (referencingEntry.location)
                {
                case Location.ScriptAsset:
                case Location.ScriptableObjectAsset:

                    if (!CSSelectionTools.RevealAndSelectFileAsset(assetPath))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }

                    break;

                case Location.PrefabAssetObject:
                    if (!CSSelectionTools.RevealAndSelectSubAsset(assetPath, referencingEntry.transformPath, referencingEntry.objectId))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                    break;

                case Location.PrefabAssetGameObject:
                case Location.SceneGameObject:

                    if (!CSSelectionTools.RevealAndSelectGameObject(assetPath, referencingEntry.transformPath, referencingEntry.objectId, referencingEntry.componentId))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                    break;

                case Location.SceneLightingSettings:

                    if (!CSMenuTools.ShowSceneSettingsLighting())
                    {
                        Debug.LogError(Maintainer.ConstructError("Can't open Lighting settings!"));
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                    break;

                case Location.SceneNavigationSettings:

                    if (!CSMenuTools.ShowSceneSettingsNavigation())
                    {
                        Debug.LogError(Maintainer.ConstructError("Can't open Navigation settings!"));
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                    break;

                case Location.NotFound:
                case Location.Invisible:
                    break;

                case Location.TileMap:

                    if (!CSSelectionTools.RevealAndSelectGameObject(assetPath, referencingEntry.transformPath, referencingEntry.objectId, referencingEntry.componentId))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }

                    // TODO: open tilemap editor window?

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                if (item.data.assetSettingsKind == AssetSettingsKind.NotSettings)
                {
                    if (!CSSelectionTools.RevealAndSelectFileAsset(assetPath))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                }
                else
                {
                    if (!CSEditorTools.RevealInSettings(item.data.assetSettingsKind, assetPath))
                    {
                        MaintainerWindow.ShowNotification("Can't show it properly");
                    }
                }
            }
        }
Exemple #25
0
        private static bool ScanProjectFiles(ICollection <CleanerRecord> results, bool showProgress = true)
        {
            currentPhase++;

            List <string> ignoredScenes = new List <string>();

            if (MaintainerSettings.Cleaner.ignoreScenesInBuild)
            {
                ignoredScenes.AddRange(CSSceneTools.GetScenesInBuild(!MaintainerSettings.Cleaner.ignoreOnlyEnabledScenesInBuild));
            }

            CheckScenesForExistence(results, ignoredScenes, "Scenes in build");

            foreach (string scene in MaintainerSettings.Cleaner.sceneIgnores)
            {
                if (!ignoredScenes.Contains(scene))
                {
                    ignoredScenes.Add(scene);
                }
            }

            CheckScenesForExistence(results, ignoredScenes, "Scene Ignores");

            if (ignoredScenes.Count == 0)
            {
                results.Add(CleanerErrorRecord.Create("No ignored scenes, terminating unused assets search!"));
                return(false);
            }

            List <string> ignores = MaintainerSettings.Cleaner.pathIgnores.ToList();

            ignores.Add("Assets/Editor Default Resources");
            ignores.Add("/Resources/");
            ignores.Add("/StreamingAssets/");
            ignores.Add("/Gizmos/");
            ignores.Add("/Editor/");
            ignores.Add("/Plugins/");
            ignores.Add(".dll");
            ignores.Add(".rsp");
            ignores.AddRange(ignoredScenes);
            ignores.AddRange(CSEditorTools.FindAssetsFiltered("t:Script"));

            List <string> assets                 = new List <string>();
            List <string> usedAssets             = new List <string>();
            List <string> assetsWithDependencies = new List <string>();

            string[] allAssets = CSEditorTools.FindAssetsFiltered("t:Object t:GUISkin", null, ignores.ToArray());
            int      count     = allAssets.Length;

            for (int i = 0; i < count; i++)
            {
                if (showProgress && EditorUtility.DisplayCancelableProgressBar(string.Format(PROGRESS_CAPTION, currentPhase, phasesCount, i + 1, count), "Gathering all assets...", (float)i / count))
                {
                    return(true);
                }

                string asset = allAssets[i];

                if (File.Exists(asset))
                {
                    if (assets.IndexOf(asset) == -1)
                    {
                        assets.Add(asset);
                    }
                }
            }

            assetsWithDependencies.AddRange(ignoredScenes);

            List <string> foldersAddedToBuild = new List <string>();

            foldersAddedToBuild.AddRange(CSEditorTools.FindFoldersFiltered("Resources"));
            foldersAddedToBuild.AddRange(CSEditorTools.FindFoldersFiltered("StreamingAssets"));

            assetsWithDependencies.AddRange(CSEditorTools.FindAssetsInFolders("t:Object t:GUISkin", foldersAddedToBuild.ToArray()));

            count = assetsWithDependencies.Count;

            for (int i = 0; i < count; i++)
            {
                if (showProgress && EditorUtility.DisplayCancelableProgressBar(string.Format(PROGRESS_CAPTION, currentPhase, phasesCount, i + 1, count), "Looking for dependencies...", (float)i / count))
                {
                    return(true);
                }

                string[] dependencies = AssetDatabase.GetDependencies(new [] { assetsWithDependencies[i] });

                foreach (string dependency in dependencies)
                {
                    if (!File.Exists(dependency))
                    {
                        continue;
                    }

                    if (usedAssets.IndexOf(dependency) == -1)
                    {
                        usedAssets.Add(dependency);
                    }
                }
            }

            foreach (string usedAsset in usedAssets)
            {
                if (assets.IndexOf(usedAsset) != -1)
                {
                    assets.Remove(usedAsset);
                }
            }

            foreach (string asset in assets)
            {
                results.Add(AssetRecord.Create(RecordType.UnusedAsset, asset));
            }

            return(false);
        }
        // ----------------------------------------------------------------------------
        // fix missing component
        // ----------------------------------------------------------------------------

        private static bool FixMissingComponents(GameObjectIssueRecord issue, GameObject go, bool alternative)
        {
            var touched = false;

#if UNITY_2019_1_OR_NEWER
            var removedCount = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(go);
            if (removedCount > 0)
            {
                touched = true;
            }
#else
            if (!alternative)
            {
                CSObjectTools.SelectGameObject(go, issue.Location == RecordLocation.Scene);
            }

            var tracker = CSEditorTools.GetActiveEditorTrackerForSelectedObject();
            if (tracker == null)
            {
                Debug.LogError(Maintainer.ConstructError("Can't get active tracker."));
                return(false);
            }
            tracker.RebuildIfNecessary();

            var activeEditors = tracker.activeEditors;
            for (var i = activeEditors.Length - 1; i >= 0; i--)
            {
                var editor = activeEditors[i];
                if (editor.serializedObject.targetObject == null)
                {
                    Object.DestroyImmediate(editor.target, true);
                    touched = true;
                }
            }

            if (alternative)
            {
                return(touched);
            }

            if (!touched)
            {
                // missing script could be hidden with hide flags, so let's try select it directly and repeat
                var serializedObject = new SerializedObject(go);
                var componentsArray  = serializedObject.FindProperty("m_Component");
                if (componentsArray != null)
                {
                    for (var i = componentsArray.arraySize - 1; i >= 0; i--)
                    {
                        var componentPair   = componentsArray.GetArrayElementAtIndex(i);
                        var nestedComponent = componentPair.FindPropertyRelative("component");
                        if (nestedComponent != null)
                        {
                            if (MissingReferenceDetector.IsPropertyHasMissingReference(nestedComponent))
                            {
                                var instanceId = nestedComponent.objectReferenceInstanceIDValue;
                                if (instanceId == 0)
                                {
                                    var fileId = nestedComponent.FindPropertyRelative("m_FileID");
                                    if (fileId != null)
                                    {
                                        instanceId = fileId.intValue;
                                    }
                                }

                                Selection.instanceIDs = new [] { instanceId };
                                touched |= FixMissingComponents(issue, go, true);
                            }
                        }
                        else
                        {
                            Debug.LogError(Maintainer.LogPrefix + "Couldn't find component in component pair!");
                            break;
                        }
                    }

                    if (touched)
                    {
                        CSObjectTools.SelectGameObject(go, issue.Location == RecordLocation.Scene);
                    }
                }
                else
                {
                    Debug.LogError(Maintainer.LogPrefix + "Couldn't find components array!");
                }
            }
#endif
            if (touched)
            {
                if (issue.Location == RecordLocation.Scene)
                {
                    CSSceneTools.MarkSceneDirty();
                }
                else
                {
                    EditorUtility.SetDirty(go);
                }
            }

            return(touched);
        }
Exemple #27
0
        public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
        {
            var columns = new[]
            {
                new MultiColumnHeaderState.Column
                {
                    headerContent       = new GUIContent(string.Empty, "Referenced Object kind: Game Object or Component"),
                    headerTextAlignment = TextAlignment.Center,
                    canSort             = false,
                    width                 = 22,
                    minWidth              = 22,
                    maxWidth              = 22,
                    autoResize            = false,
                    allowToggleVisibility = false,
                    contextMenuText       = "Icon"
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent         = new GUIContent(CSEditorTools.NicifyName(Columns.GameObject.ToString()), "Game Object name including full hierarchy path"),
                    headerTextAlignment   = TextAlignment.Left,
                    sortedAscending       = true,
                    canSort               = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width                 = 200,
                    minWidth              = 200,
                    autoResize            = true,
                    allowToggleVisibility = false
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent         = new GUIContent(CSEditorTools.NicifyName(Columns.Component.ToString()), "Component name"),
                    headerTextAlignment   = TextAlignment.Left,
                    sortedAscending       = true,
                    canSort               = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width                 = 100,
                    minWidth              = 90,
                    autoResize            = false,
                    allowToggleVisibility = true
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent         = new GUIContent(CSEditorTools.NicifyName(Columns.Property.ToString()), "Full property path to the referenced item"),
                    headerTextAlignment   = TextAlignment.Left,
                    sortedAscending       = true,
                    canSort               = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width                 = 100,
                    minWidth              = 90,
                    autoResize            = false,
                    allowToggleVisibility = true
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent         = new GUIContent("Refs", "Shows how much times object was referenced in the scene"),
                    headerTextAlignment   = TextAlignment.Left,
                    sortedAscending       = false,
                    canSort               = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width                 = 33,
                    minWidth              = 33,
                    maxWidth              = 50,
                    autoResize            = false,
                    allowToggleVisibility = true,
                }
            };

            var state = new MultiColumnHeaderState(columns)
            {
                sortedColumns     = new[] { 1, 4 },
                sortedColumnIndex = 4
            };

            return(state);
        }
        internal static void TryAddEntryToMatchedConjunctions(Object lookAt, int lookForInstanceId, EntryAddSettings settings)
        {
            var lookAtGameObject = lookAt as GameObject;

            for (var i = 0; i < assetConjunctions.conjunctions.Count; i++)
            {
                var conjunction            = assetConjunctions.conjunctions[i];
                var referencedAssetObjects = conjunction.referencedAsset.GetAllAssetObjects();

                var match = false;
                for (var j = 0; j < referencedAssetObjects.Length; j++)
                {
                    if (referencedAssetObjects[j] != lookForInstanceId)
                    {
                        continue;
                    }

                    match = true;
                    break;
                }

                if (!match)
                {
                    continue;
                }

                if (currentObjectCache == null)
                {
                    currentObjectCache          = new CachedObjectData();
                    currentObjectCache.objectId = CSObjectTools.GetUniqueObjectId(lookAt);

                    if (currentLocation == Location.SceneGameObject || currentLocation == Location.PrefabAssetGameObject)
                    {
                        if (lookAtGameObject != null)
                        {
                            var transform = lookAtGameObject.transform;
                            currentObjectCache.transformPath = CSEditorTools.GetFullTransformPath(transform);
                        }
                        else
                        {
                            currentObjectCache.transformPath = lookAt.name;
                        }
                    }
                    else if (currentLocation == Location.PrefabAssetObject)
                    {
                        currentObjectCache.transformPath = lookAt.name;
                    }
                    else
                    {
                        currentObjectCache.transformPath = string.Empty;
                    }
                }

                var newEntry = new ReferencingEntryData
                {
                    location      = currentLocation,
                    objectId      = currentObjectCache.objectId,
                    transformPath = currentObjectCache.transformPath
                };

                if (settings != null)
                {
                    newEntry.componentName = settings.componentName;
                    newEntry.componentId   = settings.componentIndex;
                    newEntry.prefixLabel   = settings.prefix;
                    newEntry.suffixLabel   = settings.suffix;
                    newEntry.propertyPath  = settings.propertyPath;
                }

                conjunction.referencedAtInfo.AddNewEntry(newEntry);
            }
        }
Exemple #29
0
        private static bool UpdateMap(AssetsMap map)
        {
            // ----------------------------------------
            // getting all valid assets within project
            // ----------------------------------------
            if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 1 of 4", "Getting all valid assets...", 0))
            {
                Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                return(false);
            }

            var allAssetPaths  = AssetDatabase.GetAllAssetPaths();
            var validNewAssets = new List <RawAssetInfo>(allAssetPaths.Length);

            foreach (var assetPath in allAssetPaths)
            {
                /*if (assetPath.Contains(@"ScriptableObjectScriptWithMissingScript"))
                 * {
                 *      Debug.Log(assetPath);
                 * }*/

                var kind = CSEditorTools.GetAssetKind(assetPath);
                if (kind == AssetKind.Unsupported)
                {
                    continue;
                }

                if (!File.Exists(assetPath))
                {
                    continue;
                }
                if (AssetDatabase.IsValidFolder(assetPath))
                {
                    continue;
                }

                var guid    = AssetDatabase.AssetPathToGUID(assetPath);
                var rawInfo = new RawAssetInfo
                {
                    path = CSPathTools.EnforceSlashes(assetPath),
                    guid = guid,
                    kind = kind,
                };

                validNewAssets.Add(rawInfo);
            }

            // -----------------------------
            // checking existing map assets
            // -----------------------------

            if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 2 of 4", "Checking existing assets in map...", 0))
            {
                Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                return(false);
            }

            var count = map.assets.Count;

#if !UNITY_2020_1_OR_NEWER
            var updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1);
#endif
            for (var i = count - 1; i > -1; i--)
            {
#if !UNITY_2020_1_OR_NEWER
                if (i % updateStep == 0 && i != 0)
#endif
                {
                    var index = count - i;
                    if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 2 of 4", "Checking existing assets in map..." + index + "/" + count, (float)index / count))
                    {
                        EditorUtility.ClearProgressBar();
                        Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                        return(false);
                    }
                }

                var assetInMap = map.assets[i];
                if (assetInMap.Exists())
                {
                    validNewAssets.RemoveAll(a => a.guid == assetInMap.GUID);
                    assetInMap.UpdateIfNeeded();
                }
                else
                {
                    assetInMap.Clean();
                    map.assets.RemoveAt(i);
                }
            }

            // ------------------------
            // dealing with new assets
            // ------------------------

            if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 3 of 4", "Looking for new assets...", 0))
            {
                Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                return(false);
            }

            count = validNewAssets.Count;
#if !UNITY_2020_1_OR_NEWER
            updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1);
#endif
            for (var i = 0; i < count; i++)
            {
#if !UNITY_2020_1_OR_NEWER
                if (i % updateStep == 0 && i != 0)
#endif
                {
                    if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 3 of 4",
                                                                   "Looking for new assets..." + (i + 1) + "/" + count, (float)i / count))
                    {
                        Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                        return(false);
                    }
                }

                var rawAssetInfo     = validNewAssets[i];
                var rawAssetInfoPath = rawAssetInfo.path;

                var type = AssetDatabase.GetMainAssetTypeAtPath(rawAssetInfoPath);
                if (type == null)
                {
                    var loadedAsset = AssetDatabase.LoadMainAssetAtPath(rawAssetInfoPath);
                    if (loadedAsset == null)
                    {
                        if (rawAssetInfo.kind != AssetKind.FromPackage)
                        {
                            if (!CSAssetTools.IsAssetScriptableObjectWithMissingScript(rawAssetInfoPath))
                            {
                                Debug.LogWarning(Maintainer.LogPrefix + "Can't retrieve type of the asset:\n" +
                                                 rawAssetInfoPath);
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        type = loadedAsset.GetType();
                    }
                }

                var settingsKind = rawAssetInfo.kind == AssetKind.Settings ? GetSettingsKind(rawAssetInfoPath) : AssetSettingsKind.NotSettings;

                var asset = AssetInfo.Create(rawAssetInfo, type, settingsKind);
                map.assets.Add(asset);
            }

            if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 4 of 4", "Generating links...", 0))
            {
                Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                return(false);
            }

            count = map.assets.Count;

#if !UNITY_2020_1_OR_NEWER
            updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1);
#endif
            for (var i = 0; i < count; i++)
            {
#if !UNITY_2020_1_OR_NEWER
                if (i % updateStep == 0 && i != 0)
#endif
                {
                    if (EditorUtility.DisplayCancelableProgressBar("Updating Assets Map, phase 4 of 4", "Generating links..." + (i + 1) + "/" + count, (float)i / count))
                    {
                        Debug.LogError(Maintainer.LogPrefix + "Assets Map update was canceled by user.");
                        return(false);
                    }
                }

                var asset = map.assets[i];

                if (!asset.needToRebuildReferences)
                {
                    continue;
                }

                var dependencies   = asset.dependenciesGUIDs;
                var referenceInfos = new List <AssetReferenceInfo>(asset.assetReferencesInfo);

                foreach (var mapAsset in map.assets)
                {
                    var referencedAtInfos = new List <ReferencedAtAssetInfo>(mapAsset.referencedAtInfoList);

                    foreach (var dependency in dependencies)
                    {
                        if (mapAsset.GUID != dependency)
                        {
                            continue;
                        }
                        if (mapAsset.Type == asset.Type && asset.Type == CSReflectionTools.fontType)
                        {
                            continue;
                        }

                        var referencedAtInfo = new ReferencedAtAssetInfo()
                        {
                            assetInfo = asset
                        };
                        referencedAtInfos.Add(referencedAtInfo);

                        var referenceInfo = new AssetReferenceInfo()
                        {
                            assetInfo = mapAsset
                        };
                        referenceInfos.Add(referenceInfo);
                    }

                    mapAsset.referencedAtInfoList = referencedAtInfos.ToArray();
                }

                asset.assetReferencesInfo     = referenceInfos.ToArray();
                asset.needToRebuildReferences = false;
            }

            /*Debug.Log("Total assets in map: " + map.assets.Count);
             * foreach (var mapAsset in map.assets)
             * {
             *      //if (!(mapAsset.path.Contains("frag_ab") || mapAsset.path.Contains("frag_ac"))) continue;
             *      if (!mapAsset.Path.Contains("NewAssembly")) continue;
             *
             *      Debug.Log("==================================================\n" + mapAsset.Path + "\n" + mapAsset.Path);
             *      Debug.Log("[REFERENCED BY]");
             *      foreach (var reference in mapAsset.referencedAtInfoList)
             *      {
             *              Debug.Log(reference.assetInfo.Path);
             *      }
             *
             *      Debug.Log("[REFERENCES]");
             *      foreach (var reference in mapAsset.assetReferencesInfo)
             *      {
             *              Debug.Log(reference.assetInfo.Path);
             *      }
             * }*/

            return(true);
        }
Exemple #30
0
        public static ReferencingEntryData CreateNewReferenceEntry(Location currentLocation, Object lookAt, GameObject lookAtGameObject, EntryAddSettings settings)
        {
            var lookAtInstanceId = lookAt.GetInstanceID();
            CachedObjectData cachedObject;

            if (CachedObjects.ContainsKey(lookAtInstanceId))
            {
                cachedObject = CachedObjects[lookAtInstanceId];
            }
            else
            {
                cachedObject = new CachedObjectData
                {
                    objectId         = CSObjectTools.GetUniqueObjectId(lookAt),
                    objectInstanceId = lookAt.GetInstanceID(),
                };

                if (currentLocation == Location.SceneGameObject || currentLocation == Location.PrefabAssetGameObject)
                {
                    if (lookAtGameObject != null)
                    {
                        var transform = lookAtGameObject.transform;
                        cachedObject.transformPath = CSEditorTools.GetFullTransformPath(transform);
                    }
                    else
                    {
                        cachedObject.transformPath = lookAt.name;
                    }
                }
                else if (currentLocation == Location.PrefabAssetObject)
                {
                    cachedObject.transformPath = lookAt.name;
                }
                else
                {
                    cachedObject.transformPath = string.Empty;
                }

                CachedObjects.Add(lookAtInstanceId, cachedObject);
            }

            var newEntry = new ReferencingEntryData
            {
                location         = currentLocation,
                objectId         = cachedObject.objectId,
                objectInstanceId = cachedObject.objectInstanceId,
                transformPath    = cachedObject.transformPath
            };

            if (settings != null)
            {
                newEntry.componentName       = settings.componentName;
                newEntry.componentId         = settings.componentIndex;
                newEntry.componentInstanceId = settings.componentInstanceId;
                newEntry.prefixLabel         = settings.prefix;
                newEntry.suffixLabel         = settings.suffix;
                newEntry.propertyPath        = settings.propertyPath;
            }

            return(newEntry);
        }