この記事でのバージョン
Unity 2018.4.13f1
はじめに
以前「移動する可能性のある任意のアセットやディレクトリ(フォルダ)のパスを取得する方法」
という記事を投稿した際に
CallerFilePathというものの存在を知りました。
わたしはCallerFilePathを使いますねー
— スーギ・ノウコ自治区 (@pCYSl5EDgo) 2019年12月16日
ということで今回は、CallerFilePathを使ってみようという感じの記事です!
CallerFilePath
そもそもCallerFilePathとはなんぞやという話からですが、
C#(というか.NET)の属性で、ドキュメントには以下のようにあります。
呼び出し元を格納するソースファイルの完全パスを取得できるようにします。 これは、コンパイル時のファイルパスです。
つまりCallerFilePathとはメソッドを呼び出し元のファイルのパスを得るためのものです。
ちなみにCallerMemberNameで呼び出し元のメソッド名、
CallerLineNumberで呼び出し元の行数を取得する事も可能です。
実際に使う際は以下のような感じでメソッドの引数に属性を付与します。
/// <summary> /// 呼び出し元の情報をログで表示する /// </summary> public static void ShowTraceLog( [CallerMemberName] string memberName = "", //呼び出し元のメソッド名 [CallerFilePath] string sourceFilePath = "", //呼び出し元のファイルのパス [CallerLineNumber] int sourceLineNumber = 0 //呼び出し元の行数 ){ Debug.Log("呼び出し元のメソッド名 : " + memberName); Debug.Log("呼び出し元のファイルのパス : " + sourceFilePath); Debug.Log("呼び出し元の行数 : " + sourceLineNumber); }
例えばこれをAssets直下にあるNewBehaviourScript.csから実行すると、
using UnityEngine; using System.Runtime.CompilerServices;//Caller系の属性を使うのに必要 public class NewBehaviourScript : MonoBehaviour { private void Start(){ ShowTraceLog(); } /// <summary> /// 呼び出し元の情報をログで表示する /// </summary> public static void ShowTraceLog( [CallerMemberName] string memberName = "", //呼び出し元のメソッド名 [CallerFilePath] string sourceFilePath = "", //呼び出し元のファイルのパス [CallerLineNumber] int sourceLineNumber = 0 //呼び出し元の行数 ){ Debug.Log("呼び出し元のメソッド名 : " + memberName); Debug.Log("呼び出し元のファイルのパス : " + sourceFilePath); Debug.Log("呼び出し元の行数 : " + sourceLineNumber); } }
NewBehaviourScript.csへのパスや呼び出したメソッドであるStart、
さらに呼び出し元の行数も取得出来ている事が分かります。
もちろん、別のスクリプトから実行する事も可能です。
using UnityEngine; public class Sample : MonoBehaviour { private void Awake() { NewBehaviourScript.ShowTraceLog(); } }
ちなみに、Assets以下のパスが欲しい場合は
AssetsまでのパスであるApplication.dataPathを使って相対パスを取得するのが良さそうです。
using UnityEngine; using System;//Uriを使うのに必要 using System.Runtime.CompilerServices;//Caller系の属性を使うのに必要
/// <summary> /// 呼び出し元の情報をログで表示する /// </summary> public static void ShowTraceLog([CallerFilePath]string sourceFilePath = ""){ //呼び出し元のパス Debug.Log("sourceFilePath : " + sourceFilePath); //Assetsまでのパス Debug.Log("dataPath : " + Application.dataPath); //呼び出し元のパスをAssetsからのパスに変換 string relativePath = (new Uri(Application.dataPath)).MakeRelativeUri(new Uri(sourceFilePath)).ToString(); Debug.Log("relativePath : " + relativePath); }
ただし、CallerFilePathは呼び出し元のパスを取得するので、
スクリプト自身がどこにいるのかを知りたい場合は、
以下のように自分自身のパスを教えてくれるメソッドを作る必要があります。
using System;//Uriを使うのに必要 using System.Runtime.CompilerServices;//Caller系の属性を使うのに必要
/// <summary> /// 呼び出し元のパスを取得 /// </summary> public static string GetSelfPath([CallerFilePath]string sourceFilePath = ""){ return sourceFilePath; } /// <summary> /// 呼び出し元のパス(Assetsから)を取得 /// </summary> public static string GetSelfPathFromAssets([CallerFilePath]string sourceFilePath = ""){ return (new Uri(Application.dataPath)).MakeRelativeUri(new Uri(sourceFilePath)).ToString(); }
例えばこれをAssets直下にあるNewBehaviourScript.csから実行すると、以下の通りです。
Debug.Log("SelfPath : " + GetSelfPath()); Debug.Log("SelfPathFromAssets : " + GetSelfPathFromAssets());
------------追記------------
ここら辺のパス周りをいい感じに扱えるクラスを作りました!
------------追記おわり------------