frideal
4/14/2014 - 1:53 AM

Unity3d asset reference searcher.

Unity3d asset reference searcher.

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System.Linq;

public class SceneSearcher : EditorWindow
{

    [MenuItem("Window/SceneSearch")]
    static void ShoWindow()
    {
        EditorWindow.GetWindow(typeof(SceneSearcher));
    }

    Object toFind = null;

    List<Object> referenced = new List<Object>();

    void OnGUI()
    {
        if (GUI.changed)
        {
            referenced = new List<Object>();
        }

        EditorGUILayout.LabelField("Select object to find reference.");
        toFind = EditorGUILayout.ObjectField(toFind, typeof(Object), true);

        if (GUILayout.Button("Find Reference"))
        {
            referenced = new List<Object>();

            if (AssetDatabase.Contains(toFind))
            {
                var path = AssetDatabase.GetAssetPath(toFind);
                var guid = AssetDatabase.AssetPathToGUID(path);

                var referencedPaths = GetReferencedAssetPaths();
                GetReferenceObjectFromAssetPaths(referencedPaths, guid);
                Selection.objects = referenced.ToArray();
                if (referenced.Count < 1)
                {
                    Debug.LogWarning("There is no reference to object.");
                }
            }
            else
            {
                Debug.LogWarning("ToFind Object is not asset.");
            }
        }

        for (int i = 0; i < referenced.Count; i++)
        {
            referenced[i] = EditorGUILayout.ObjectField(referenced[i], typeof(Object), true);
        }
    }

    void GetReferenceObjectFromAssetPaths(List<string> referencedAssetsPath, string guid)
    {
        Debug.LogWarning("Start to search sizeof " + referencedAssetsPath.Count + " list of prefab/scenes.");
        foreach (var assetAbsolutePath in referencedAssetsPath)
        {
            bool isGUIDSearched = false;

            try
            {
                StreamReader file = new StreamReader(assetAbsolutePath);
                string line = string.Empty;
                while ((line = file.ReadLine()) != null)
                {
                    if (line.Contains(guid))
                    {
                        isGUIDSearched = true;
                        break;
                    }
                }
            }
            catch (System.ArgumentException e)
            {
                Debug.LogError(e.ToString());
                continue;
            }

            if (isGUIDSearched)
            {
                var relativeAssetName = AssetsRelativePath(assetAbsolutePath);
                var referenceObject = AssetDatabase.LoadAssetAtPath(relativeAssetName, typeof(Object));
                referenced.Add(referenceObject);
                if (referenceObject == null)
                {
                    Debug.LogError("Scene object is null.");
                }
                Debug.LogWarning("Scene : " + relativeAssetName + " Contains " + guid);
            }
        }
    }

    static List<string> GetReferencedAssetPaths()
    {
        var dir = new DirectoryInfo("Assets");
        List<string> referencedAssetPaths = new List<string>();

        GetReferencedAssetPathsIter(dir, referencedAssetPaths);

        return referencedAssetPaths;
    }

    static void GetReferencedAssetPathsIter(DirectoryInfo dir, List<string> referenceAssetNames)
    {
        var filesInfo = dir.GetFiles();
        foreach (var file in filesInfo)
        {
            if (file.Name.EndsWith(".unity") || file.Name.EndsWith(".prefab"))
            {
                referenceAssetNames.Add(file.FullName);
            }
        }
        var dirs = dir.GetDirectories();
        foreach (var subdir in dirs)
        {
            GetReferencedAssetPathsIter(subdir, referenceAssetNames);
        }
    }

    /* https://gist.github.com/mstevenson/4386682 */
    public static string AssetsRelativePath(string absolutePath)
    {
        var applicationPath = new DirectoryInfo(".").FullName;
        if (absolutePath.StartsWith(applicationPath))
        {
            return "Assets" + absolutePath.Substring(Application.dataPath.Length);
        }
        else
        {
            Debug.LogError("Error : " + absolutePath);
            Debug.LogError("Application.DataPath is " + Application.dataPath);
            Debug.LogError("DirectoryInfo . is " + applicationPath);
            throw new System.ArgumentException("Full path does not contain the current project's Assets folder", "absolutePath");
        }
    }
}