123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- public class DeleteDuplicatedObjectsEditorWindow : EditorWindow
- {
- private int deleted;
- private int skipped;
- private int overallObjects;
- [MenuItem("Window/Delete Duplicates")]
- private static void ShowWindow()
- {
- var window = GetWindow<DeleteDuplicatedObjectsEditorWindow>();
- window.titleContent = new GUIContent("Delete Duplicates");
- window.Show();
- }
- private void OnGUI()
- {
- if (GUILayout.Button("Delete Duplicates"))
- {
- OnDeleteDuplicates();
- }
- if (GUILayout.Button("Delete Everything"))
- {
- OnDeleteEverything();
- }
- GUILayout.Label($"Total number objects {overallObjects}");
- GUILayout.Label($"Deleted items: {deleted}");
- GUILayout.Label($"Skipped items: {skipped}");
- //TODO: maybe show ref to skipped items
- }
- private void OnDeleteEverything()
- {
- var objects = FindObjectsOfType<MeshRenderer>();
- foreach (var meshRenderer in objects)
- {
- if (meshRenderer == null) continue;
- var prefab = PrefabUtility.GetOutermostPrefabInstanceRoot(meshRenderer.gameObject);
- DestroyImmediate(prefab != null ? prefab : meshRenderer.gameObject);
- }
- }
- private void OnDeleteDuplicates()
- {
- skipped = 0;
- deleted = 0;
- List<GameObject> toDelete = new List<GameObject>();
- var objects = FindObjectsOfType<MeshRenderer>();
- var objectsAtPos = new Dictionary<Vector3, List<GameObject>>();
- overallObjects = objects.Length;
- Debug.Log($"Found {overallObjects} GameObjects");
- foreach (var o in objects)
- {
- var pos = o.transform.position;
- if (!objectsAtPos.ContainsKey(pos))
- {
- var l = new List<GameObject> {o.gameObject};
- objectsAtPos[pos] = l;
- }
- else
- {
- objectsAtPos[pos].Add(o.gameObject);
- }
- }
- Debug.Log($"Done sorting");
- var objs = objectsAtPos.Values.Where(l => l.Count > 1);
- var enumerable = objs as List<GameObject>[] ?? objs.ToArray();
- Debug.LogWarning($"{enumerable.Count()} gameobjects at exact same position");
- Debug.Log("Deleting objects..");
- foreach (var o in enumerable)
- {
- var rMap = new Dictionary<Quaternion, List<GameObject>>();
- foreach (var d in o)
- {
- if (d == null) continue;
- var rot = d.transform.rotation;
- if (rMap.ContainsKey(rot))
- {
- rMap[rot].Add(d);
- }
- else
- {
- rMap[rot] = new List<GameObject> {d};
- }
- //Destroy(d);
- }
- var samePosAndRot = rMap.Values.Max(v => v.Count);
- Debug.Log($"max same pos and rot = {samePosAndRot}");
- if (samePosAndRot < 2) continue;
- var resultsWithMax = rMap.Values.Where(l => l.Count == samePosAndRot);
- foreach (var r in resultsWithMax)
- {
- Debug.Log($"Names: {string.Join(",", r.Select(x => x.name))}");
- if (r.Aggregate((result, item) =>
- {
- if (result == null) return null;
- else
- {
- var rIndex = result.name.IndexOf('(');
- var iIndex = item.name.IndexOf('(');
- var rBase = rIndex > 0 ? result.name.Substring(0, rIndex) : result.name;
- var iBase = iIndex > 0 ? item.name.Substring(0, iIndex) : item.name;
- return rBase.Equals(iBase) ? item : null;
- }
- }) != null)
- {
- for (var index = 1; index < r.Count; index++)
- {
- var gameObject1 = r[index];
- if (gameObject1.transform.childCount == 0)
- {
- var prefabParent = PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject1);
- if (prefabParent != null)
- {
- Debug.LogWarning($"Destroyed prefab {prefabParent.name}!");
- //DestroyImmediate(prefabParent);
- toDelete.Add(prefabParent);
- }
- else
- {
- toDelete.Add(gameObject1);
- //DestroyImmediate(gameObject1);
- }
- }
- else
- {
- Debug.LogError($"Did not destroy {gameObject1.name}");
- skipped++;
- }
- deleted++;
- }
- }
- }
- }
- foreach (var d in toDelete)
- {
- if (d != null)
- {
- DestroyImmediate(d);
- }
- }
- Debug.LogWarning($"Deleted {deleted} items!");
- Debug.LogWarning($"Skipped {skipped} items!");
- }
- }
|