😀

【Unity】UPM対応時のパスの変更に対応する

2025/01/13に公開

はじめに

UPM対応時、パッケージに含めたアセット(Prefab, Texture, etc...)に
アクセスしようとすると開発環境下とPackage内ではパスが異なることに気が付くでしょう。

SerializeFieldなどを利用することができればよいですが、
Editorメニューからアクセスしたいときなどに利用されるstaticメソッド内では利用できません。

今回は自身のソースファイルのパスを開発環境下・Packages内問わず
Unityで利用可能な相対パスとして取得する方法を解説していきます。

前提

先ほど述べさせていただいたUnityで利用可能な相対パスとは
開発環境下においてはAssets\開発環境下へのパス\...
Packages内においてはPackages\正式なパッケージ名\...のことを指します。
……が2025/01/14に改めて検証したところどちらも絶対パス指定で良いようです。
再検証の結果上記が間違いであることが判明いたしました。

https://docs.unity3d.com/ja/2021.2/Manual/upm-assets.html

今回はソースファイルのパスからUnityで利用可能な相対パスを取得するため

Sample.cs
private static string GetSourceFilePath([CallerFilePath]string sourceFilePath = "")
{
  return souceFilePath
}

を利用します。

上記を呼び出すと
開発環境下においてはドライブから開発環境下までのパス\Sample.csへのパス
Packages内においては.\Library\PackageCache\正式なパッケージ名@16進数表記の識別番号\Sample.csへのパス
という結果を得ることができます。

https://zenn.dev/masaki_mori72/articles/4be11ef55d3b95

実装

前提から行うべき処理を以下のように定義しました。

  1. パスが.から始まるかを条件に分岐する

1がfalseならパスを返却。1がtrueなら次へ

  1. .\Library\PackageCache\Packages\
    正式なパッケージ名@16進数表記の識別番号正式なパッケージ名に変換する。
  2. 変換結果を結合して返却する。

これを基に、コードでは以下のように定義します。

Sample.cs
/// <summary>
/// ソースファイルのパスを取得
/// </summary>
/// <param name="sourceFilePath">コンパイル時に解釈</param>
/// <returns>Unityで利用可能な相対パス</returns>
private static string GetSourceFilePathForUnity([System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "")
{
    if (sourceFilePath[0] != '.') { return sourceFilePath; }
    sourceFilePath = sourceFilePath[23..];  // ".\Library\PackageCache\"を削除
    string packageName = sourceFilePath.Substring(0, sourceFilePath.IndexOf('@'));
    int delimiterIndex = sourceFilePath.IndexOf(@"\"[0]);
    sourceFilePath = sourceFilePath.Substring(delimiterIndex, sourceFilePath.Length - delimiterIndex);
    return @"Packages\" + packageName + sourceFilePath;
}

このように処理を行うことで開発環境下・Packages内問わず処理を行うことができます。

実際に利用するときはパッケージ直下に上記コードを定義したスクリプトを配置し、
返却値をSystem.IO.Path.GetDirectoryName()に通すことで
パッケージまでのパスを取得する等の方法が考えられます。

さいごに

ご覧いただき、ありがとうございました。
UPM対応時の一助となれば幸いです。

(2025/01/13)
寒い日が続きますので、お身体にはお気をつけてお過ごしください。

Discussion