Unity で作成した、影用タイルマップ関数のテストで、スクリプトのファイルパスが必要になったので調べました。
ファイルパス・アセットパスを取得するコードと、その使用例・結果とともに紹介します。
※ Unity は 2021.3.14f1、Test Framework パッケージは Version 1.1.33、Visual Studio は Community 版 Version 17.2.5、 OS は Windows 10 です。
アセットパスという造語について
以前にも触れましたが、アセットパスは筆者が便宜的に Windows のファイルパスと区別するために使っている言葉であり公式などに記載されているかは確認していません。
ここでいうアセットパスは、 Unity プロジェクトフォルダを相対パスとして Assets から始まる区切り文字が / (スラッシュ) のパスを指します。
Unity スクリプトファイルのパス取得コード
Unity Assets フォルダ内にあるスクリプトファイル自身のファイルパスを取得します。
パスの形式は、OS (Windows の場合) が認識する “C:\Unity\MyProject\Assets\Hoge/Piyo.cs” のような絶対ファイルパス形式です。
/// <summary>
/// スクリプトのファイルパス(OS の絶対ファイルパス)を取得します。
/// </summary>
/// <param name="filePath">自動的に設定されます。</param>
/// <returns>ファイルパス</returns>
/// <see cref="roslyn - C# for scripting (csx) location of script file - Stack Overflow - https://stackoverflow.com/questions/46728845/c-sharp-for-scripting-csx-location-of-script-file>"/>
public static string GetFilePath([System.Runtime.CompilerServices.CallerFilePath] string filePath = null)
{
return filePath;
}
GetFilePath 関数の引数の前にある [System.Runtime.CompilerServices.CallerFilePath] 属性がポイントです。
この属性は呼び出し元情報を用いて、この GetFilePath 関数の呼び出し元のファイルパスを引数の文字列に与えてくれます。
この属性をつける引数にはデフォルト引数が必要です。
これにより、実際に呼び出す際は引数を指定しないで GetFilePath() のように呼び出せます。
公式ドキュメント「C# コンパイラによって解釈される属性: 呼び出し元情報の追跡 | Microsoft Learn」にも書いてある通り、デバッグや診断ツール開発に利用されることを想定しているようです。
他の呼び出し元情報
ファイルパスの他に、呼び出し元の行番号や関数名なども取得できます。
- CallerFilePathAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerLineNumberAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerMemberNameAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerArgumentExpressionAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
アセットパスへの変換
正確ではないかもしれませんが、 Assets フォルダをトップにしたパスをアセットパスと呼ぶことにしました。
“Assets/Hoge/Piyo.cs” みたいなパスです。
先ほどは OS で認識できる絶対ファイルパスを取得したので、それをアセットパスへと変換します。
/// <summary>
/// ファイルパスをアセットパスへ変換します。
/// <see cref="AssetDatabase-GetAssetPath - Unity スクリプトリファレンス - https://docs.unity3d.com/ja/2018.4/ScriptReference/AssetDatabase.GetAssetPath.html>"/>
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public static string ConvertAssetPath(string filePath)
{
return filePath.Replace(System.IO.Path.DirectorySeparatorChar, '/').Replace(Application.dataPath, "Assets");
}
まずはファイルパスの区切り文字が OS によって / だった \ だったりするので、それをアセットパスの区切り文字 / に置換します。
次に、 Assets から始まるパスに変換します。これは文字列の置換で行います。
Application.dataPath には OS が認識する絶対パスで Unity プロジェクトの Assets フォルダまでの絶対パスが定義されています。
その部分は、前述した関数の前半に含まれているので、その部分を Assets に置き換えます。
これにより、スクリプトのファイルパスと変換したアセットパスが取得できました。
使用例
今回は、Assets フォルダ内のテスト用の cs スクリプトファイルに次のようなコードを書きました。
string filePath = SCPath.GetFilePath();
Debug.Log("filePath = " + filePath);
string assetPath = SCPath.ConvertAssetPath(filePath);
Debug.Log("assetPath = " + assetPath);
紹介した関数二つを呼び出すコードをテスト関数に書いて Test Runner で実行しました。
Test Runner ウィンドウは Unity エディタメニュー[Window] → [General] → [Test Runner] で開きます。
その結果として次のようなログが出力されました。
filePath = G:\Dev\Unity\Unity1Week24Re\Assets\SakuraCrowd\Tools\TestsSCTools\TestSCPath.cs
assetPath = Assets/SakuraCrowd/Tools/TestsSCTools/TestSCPath.cs
このテストコードが書かれているファイルのファイルパスとアセットパスを取得できました。
まとめ
今回は、Unity の Assets フォルダ内の cs スクリプトファイル自身のファイルパスを取得するコードを紹介しました。
Unity のアセットパスと Windows のファイルパスでは区切り文字が違うので、その変換や、 Unity プロジェクトからの Assets から始まる相対パスへの変換についても紹介しました。
また文字列の置換により、アセットパスへと変換するコードも紹介しました。
参照サイト Thank You!
- Unity のリアルタイム開発プラットフォーム | 3D/2D、VR/AR のエンジン
- C# コンパイラによって解釈される属性: 呼び出し元情報の追跡 | Microsoft Learn
- CallerFilePathAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerLineNumberAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerMemberNameAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- CallerArgumentExpressionAttribute クラス (System.Runtime.CompilerServices) | Microsoft Learn
- C# for scripting (csx) location of script file – Stack Overflow
- AssetDatabase-GetAssetPath – Unity スクリプトリファレンス
記事一覧 → Compota-Soft-Press
コメント