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)); } }
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); } }
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); } }
/// <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); } }
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); }
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); }
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); } }
// ---------------------------------------------------------------------------- // 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]); } } } } }
/// <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))); } } }
protected override string GetReportHeader() { return(resultsStats != null ? "Total found garbage size: " + CSEditorTools.FormatBytes(resultsStats.totalSize) : null); }
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); }
public void Show() { CSEditorTools.RevealInSettings(SettingsKind); }
// ----------------------------------------------------------------------------- // 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); }
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"); } } } }
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); }
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); } }
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); }
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); }