読者です 読者をやめる 読者になる 読者になる

(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

Resources内にあるファイルとディレクトリへのパスを自動作成する【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 5.1.0f3 Personal

はじめに

Resources.Loadを使ってPrefabからインスタンスを作る、みたいな事はよくあると思います。

しかし、Prefabのパスを文字列で指定するのが難点で、どうにかしてパスを自動作成したいですよね。


という事で今回はResourcesディレクトリ内のファイルに対するパスを自動作成してみました。


使用例

例えば、MainCameraというPrefabBlackというテクスチャがResourcesディレクトリ内に入ってる時、


f:id:kan_kikuchi:20151002133059p:plain


それぞれのファイル及びディレクトリへのパスが以下のような形で自動作成されます。

/// <summary>
/// Resources以下のファイルパスを定数で管理するクラス
/// </summary>
public static class ResourcesFilePath{

  public const string PREFAB_MAIN_CAMERA = "Main Camera";
  public const string TEXTURE_BLACK      = "Child/Black";

}
/// <summary>
/// Resources以下のディレクトリパスを定数で管理するクラス
/// </summary>
public static class ResourcesDirectoryPath{

  public const string CHILD = "Child";

}
Resources.Load    (ResourcesFilePath.PREFAB_MAIN_CAMERA);
Resources.LoadAll (ResourcesDirectoryPath.CHILD);


こうすればパスを文字列でしなくていいですし、

パスが変わった時もコードを修正しなくていい、もしくはエラーになってすぐ分かります。


なお、ファイル数が多くなると処理に時間がかかりそうなので、定数クラスの自動更新はしていません。



ResourcesPathClassCreator

ではさっそくコードです。



上記のConstantsClassCreator.csResourcesPathClassCreator.csEditorディレクトリに入れ、


f:id:kan_kikuchi:20151002134604p:plain


Tools - Create - ResourcesPath Class を実行すると、


f:id:kan_kikuchi:20151002134616p:plain


最初の例に載せたResourcesFilePath.csResourcesDirectoryPath.csが作成されます。


例のようにResourcesディレクトリは複数有ってもいいですし、どこにあっても大丈夫です。

もちろんResourcesディレクトリ以下に子/孫/…のようにディレクトリがいくら続いていても大丈夫です。


また、ResourcesFilePath.csとResourcesDirectoryPath.csはAssets直下に作成されますが、

作成場所はConstantsClassCreatorの以下の部分を編集する事で変えられます。

string exportPath = "Assets/" + className + ".cs";


ConstantsClassCreatorについては以前書いた以下の記事をどうぞ!



ようは定数を管理するクラス(を記載したスクリプト)を生成するクラスです。


コード説明

まず処理の流れは以下の通りです。

  1. 全Resourcesディレクトリへのパスを取得
  2. 各Resourcesディレクトリ直下の全ファイルのパスを取得
  3. 各Resourcesディレクトリ内の全ディレクトリのパスを取得、その中にある全ファイルのパスも取得
  4. 拡張子とタイプの対応から定数名を決定
  5. 定数クラスを作成


各パスはResourcesディレクトリからの相対パスという点に注意が必要です。

次に細かいところを説明していきます。


パスを取得

ディレクトリの検索はDirectory.GetDirectoriesを用いて行っています。

//Assets以下にある全Resourcesディレクトリへのパスを取得
string[] resourcesDirectoryPaths = Directory.GetDirectories ("Assets", "Resources", SearchOption.AllDirectories);

//parentPath以下の全ディレクトリへのパスを取得
string[] childPaths = Directory.GetDirectories (parentPath, "*", SearchOption.AllDirectories);


ファイルへのパスも同様にDirectory.GetFilesを用いて行っています。

//absolutePathにあるディレクトリ直下の全ファイルへのパスを取得
 string[] childPaths = Directory.GetFiles (absolutePath, "*", SearchOption.TopDirectoryOnly);


パス取得の詳しい話はこちらをどうぞ。


拡張子とタイプを対応から定数名を決定

定数名がファイル名だけだと何のファイルか分かり難いので、

GetFileTypeFromExtentionで拡張子から何のファイルか判定し定数名を決定しています。

例えばテクスチャならTEXTURE_○○○、オーディオならAUDIO_○○○といった具合です。


拡張子とタイプの対応は以下の記事を参考にしています。



また.metaファイルなど、未定義の拡張子を持ったファイルへのパスは定数として書き出していません。


おわりに

これで毎度パスの定数を作成する手間がなくなりましたね!

地味に面倒だったので重宝していたりします。