【Unity(C#)】毎回使う複数のフォルダをワンクリックで作成する方法

　　
　　
　　
この記事は

**『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』**

の記事です。そのつもりでお読みください。


##弊社には最強のエンジニアがおります
私は今の会社に入社する前、Unityで新しいプロジェクトを作成したとき(入社直前に不安過ぎて予習してた)、
`Material用のフォルダ`とか、`Script用のフォルダ`とかを毎回作ってました。

しかし、今の会社にいる最強エンジニア(上司)に、
**何度も繰り返す作業はできる限り自動化した方がいい**とアドバイスいただきました。

実際に、その最強エンジニアの方は様々なものをどんどん自動化しているので
これ以上置いていかれないためにも勉強がてら挑戦してみました。

##ほぼ毎回使うフォルダ
ワンクリックで、ほぼ毎回使うフォルダをAssetの階層の下に作成します。

CommonFolderというフォルダを作ってその下にいろいろ配置します。

今回はよく使う下記フォルダを一気に作りたいと思います。

-----
"Animations"
"AnimatorControllers"
"Editors"
"Textures"
"Materials"
"Prefabs"
"Resources"
"RenderTextures"
"Scripts"
"Scenes"
"Shaders"

----

##コード

Editor拡張なので、ゲームオブジェクトにAdd Componentする必要はありません。

```C#
using UnityEditor;
using System.IO;
public class SetFirstFolder : EditorWindow
{
    [MenuItem("Custom/CreateFolder")]
    static void CreateFolder()  //FolderName("フォルダ名");　で新しいフォルダ追加可能
    {
        
        if (AssetDatabase.IsValidFolder("Assets/CommonFolder"))
        {
            return;
        }

        FolderName("Animations");
        FolderName("AnimatorControllers");
        FolderName("Editors");
        FolderName("Textures");
        FolderName("Materials");
        FolderName("Prefabs");
        FolderName("Resources");
        FolderName("RenderTextures");
        FolderName("Scripts");
        FolderName("Scenes");
        FolderName("Shaders");

    }


    static void FolderName(string folderName)
    {
        string path = "Assets/CommonFolder/" + folderName;

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        AssetDatabase.ImportAsset(path);
    }
}
```

##解説

`[MenuItem("メニューボタン名/メニューボタン押したら出てくるボタン名")]`
これを書いたらメニューボタン的なやつ(正式名称教えてください)になります。
![Custom.png](https://qiita-image-store.s3.amazonaws.com/0/244071/0ba617db-c595-1193-2e9b-dde4b1e3a731.png)

`Directory.Exists(パス名)`
ここで指定したパス名のフォルダが存在しているか確認しています。
存在していれば`Directory.Exists(パス名)==true`となります。

`Directory.CreateDirectory(パス名)`
ここで指定したパス名のフォルダを作成しています。

`AssetDatabase.ImportAsset(パス名)`
↑に関してUnityのすくりぷとりふぁれんすには
**パスからアセットをインポートします**とあります~~が私はあほなので意味がわかりません。~~
ただ、これがないと
いちいちEditorウィンドウを閉じて、開くという作業をしないと反映されません。
なので書いときましょう。

---
2019/04/25 追記
[AssetDatabase.Refresh](https://docs.unity3d.com/ja/current/ScriptReference/AssetDatabase.Refresh.html)でもいけました。
>何かしら変更があったアセットをすべてインポートします。

とのことです。

---

```C#
 static void FolderName(string folderName)
    {
        string path = "Assets/CommonFolder/" + folderName;

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        AssetDatabase.ImportAsset(path);
    }
```

どうやら、`Directory.CreateDirectory(パス名)`を使うと、
間の階層のパス名のフォルダがなくても自動で作ってくれるようです。

例としてパスに階層を増やしてみます。

```C#
string path = "Assets/CommonFolder/Aidano/Foler/" + folderName;
```

![aidanoFolerpng.png](https://qiita-image-store.s3.amazonaws.com/0/244071/191363c2-587e-b956-40d3-1f51509339a9.png)

増えましたね。(FolderとかTextureとか誤字ってますが直すのめんどくさいのでゆるしてください)


指定したパス名のフォルダが存在しているか確認する方法として、
`AssetDatabase.IsValidFolder(パス名)`
もあります。
存在していれば`AssetDatabase.IsValidFolder(パス名)==true`です。

`CreateFolderメソッド`内で毎回使うフォルダーを作成しているか
確認し、存在する場合はreturnしてます。

```C#
if (AssetDatabase.IsValidFolder("Assets/CommonFolder"))
{
   return;
}
```

余談ですが、
`AssetDatabase.CreateFolder(親にしたいフォルダの名前, 新しく作るフォルダの名前)`
でもフォルダを作ることができます。

ただ、こちらは間の階層のパス名のフォルダ(親にしたいフォルダの名前)がない場合は
何も作ることができません。


##足りないフォルダはどんどん追加しよう
`CreateFolderメソッド`内で
`FolderName(フォルダ名)`を追記すれば足りないフォルダを自分用にカスタムできます。


便利ですね～

---
2019/05/08 追記

生成されるフォルダ名の先頭に`_(アンダースコア)`をつけとくと
最上段に表示されるのでそのほうがいいかもしれません。

```C#:例
string path = "Assets/_CommonFolder/" + folderName;
```

---
2020/02/08 追記

ビルド先のフォルダも追加で作成

```C#
#if UNITY_EDITOR
using UnityEditor;
using System.IO;
public class SetFirstFolder : EditorWindow
{
    [MenuItem("Custom/CreateFolder")]
    static void CreateEditorFolder()  //FolderCreate("フォルダ名");　で新しいフォルダ追加可能
    {

        BuildFolderCreate();

        if (AssetDatabase.IsValidFolder("Assets/_CommonFolder"))
        {
            return;
        }

        FolderCreate("Animations");
        FolderCreate("Audios");
        FolderCreate("AnimatorControllers");
        FolderCreate("Editors");
        FolderCreate("Textures");
        FolderCreate("Materials");
        FolderCreate("Prefabs");
        FolderCreate("Resources");
        FolderCreate("RenderTextures");
        FolderCreate("Scripts");
        FolderCreate("Scenes");
        FolderCreate("Shaders");
    }

    static void FolderCreate(string FolderCreate)
    {
        string path = "Assets/_CommonFolder/" + FolderCreate;

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        AssetDatabase.ImportAsset(path);
    }
    
    static void BuildFolderCreate()
    {
        string path =  "Build/";

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        AssetDatabase.ImportAsset(path);
    }
}
#endif
```