Unity里常用的一些路径等信息

时间:2021-10-22 08:15:35
0.  Asset folder的路径:Application.dataPath; 得到的是自磁盘根目录开始的路径。
0. C#自带的:  string[] paths = Directory .GetFiles(Application.dataPath, "*.*", SearchOption .AllDirectories);  //第三个参数可以改为 SearchOption  。 TopDirectoryOnly则只搜索指定的目录,不搜索下面的子目录
string[] matpaths = Directory .GetFiles(Application.dataPath, "*.mat", SearchOption .AllDirectories);  //搜索Unity工程Asset目录(包括子目录)下所有的Material

1. LoadAsset
Resources.Load,只Load位于Resources文件夹及其子目录下面的Asset。   但有Resources.LoadAssetAtPath()可以Load放置于任意位置的Asset。
Resources.LoadAssetAtPath :Returns a resource at an asset path (Editor Only).  
     This function always return null in the standalone player or web player. This is useful for quickly accessing an asset for use in the editor only.
AssetDatabase.LoadAssetAtPath : Returns the first asset object of type type at given path assetPath.
  Material mat = ( Material ) Resources .LoadAssetAtPath(propermatpath, typeof ( Material ));  
// In Editor, same with  Material  mat =  (Material)AssetDatabase.LoadAssetAtPath(propermatpath, typeof(Material));
注意!!!! 很容易导致Load fail 的两个细节!!!
(1) Unity里的各种Load,都要求路径是相对的路径 。All paths are relative to the project folder, for example: "Assets/MyTextures/hello.png".
(2) 分隔符为单个的‘/’ , Windows平台也是一样 。 ALL asset names & paths in Unity use forward slashes, even on Windows.
    static string GetRelativeAssetPath(string _fullPath)
    {
        _fullPath = GetRightFormatPath(_fullPath);
        int idx = _fullPath.IndexOf("Assets");
        string assetRelativePath = _fullPath.Substring(idx);
        return assetRelativePath;
    }

    static string GetRightFormatPath(string _path)
    {
        return _path.Replace("\\", "/");
    }

2. FindObjects
  GameObject [] objs = (  GameObject [])FindObjectsOfType( typeof  ( GameObject ));    //get all gameobjects including sub_GameObject.
         Renderer [] renderers = ( Renderer  [])FindObjectsOfType< Renderer >();
Object.FindObjectsOfType :  Returns a list of all active loaded objects of Type type. It will return no assets (meshes, textures, prefabs, ...) or inactive objects.

Resources.FindObjectsOfTypeAll : 
This function can return any type of Unity object that is loaded, including game objects, prefabs, materials, meshes, textures, etc. It will also list internal stuff, therefore please be extra careful the way you handle the returned objects. Contrary to Object.FindObjectsOfType this function will also list disabled objects.


Asset的获取,以获取Material为例
  Object [] selections = Selection .GetFiltered( typeof ( Material ), SelectionMode .TopLevel);
这里获取到Material类型的Object[], 但这里并不能直接将selections强转为Material[]。 需要将这些Materail Load进内存再处理。
// for me : 一个重要的思想是,不是想着有那些API,然后用API去迁就你的功能实现,而是把注意力放在功能上,让功能按照正常思维去做。按照这个方式去找合适的API。软件一般是按照人们的正常思维来设计的,所以按照这个流程,可以比较顺畅地实现功能需求。
如何将Material Load进内存呢,我们知道有Resources.Load(),Resources.LoadAssetAtPath(),意味着我们需要知道AssetPath然后将之Load进来。事实上,我们得到了selections,这是Object[],由Object应该可以得到它的AssetPath吧。嗯,有的, AssetDatabase .GetAssetPath(obj.GetInstanceID()); //UnityEngine.Object里有GetInstanceID(),就是为了方便大家根据InstanceID()获取Object的各种信息吧。



小技巧:

1. 测试某些功能时,可以直接在放在任意位置的.cs文件(是的,不一定要放在Editor文件夹下)里写 [MenuItem("***")] 和相应的static函数(必须是static函数)就行了。例如:
  [ MenuItem ( "IvyTrial/ClickMe" )]
    static void Clickme()
    {
        Debug .Log( "Click me" );
    }

2. C#里写数组,Object向Object[]的转换
Object [] selections = Selection .GetFiltered( typeof ( Material ), SelectionMode .TopLevel);
foreach ( Object obj in selections)
{
      Object[] roots = new Object[]{obj};
      Object [] depends = EditorUtility .CollectDependencies(roots);
}