はじめに
Scene(.unity)を開こうとしたら以下のようなエラーが表示されることがあります。

Unity Package Manager(UPM)では複数の取得方法がありますが、取得方法によってはReadOnlyなPackageになります。
Registory: readonlyBuild-in: readonlyEmbedded: editableLocal: editableTarball(local): readonlyGit: readonly
今回は特定のファイルがReadOnlyなPackageに含まれるファイルかどうかを調べる方法を紹介したいと思います。
やり方
PackageInfo.FindForAssetPathメソッドを利用することで、アセットを含むパッケージ情報を取得することができます。
public static PackageInfo FindForAssetPath(string assetPath)
Unity - Scripting API: PackageManager.PackageInfo.FindForAssetPath
ちなみにPath以外にもいくつかあるので、気になる方は公式ドキュメントを参照してください。
public static PackageInfo FindForAssembly(Compilation.Assembly assembly); public static PackageInfo FindForPackageName(string name); public static PackageInfo[] GetAllRegisteredPackages();
Unity - Scripting API: PackageInfo
PackageInfoを取得することができれば、PackageInfo.sourceを調べることでどの手法で取得したパッケージかを調べることができます。
PackageInfo packageInfo = PackageInfo.FindForAssetPath(path); // PackageSource.Local Debug.Log(packageInfo.source);
namespace UnityEditor.PackageManager { /// <summary> /// <para>Source of packages.</para> /// </summary> public enum PackageSource { /// <summary> /// <para>The package source is unknown.</para> /// </summary> Unknown, /// <summary> /// <para>The package is from a registry.</para> /// </summary> Registry, /// <summary> /// <para>The package is built-in and part of Unity.</para> /// </summary> BuiltIn, /// <summary> /// <para>The package is embedded in the Unity project.</para> /// </summary> Embedded, /// <summary> /// <para>The package is referenced by a local path.</para> /// </summary> Local, /// <summary> /// <para>The package is referenced directly by a Git URL.</para> /// </summary> Git, /// <summary> /// <para>The package is referenced by a local path pointing to a GZip tarball file.</para> /// </summary> LocalTarball, } }
コードサンプル
public class Sample { [MenuItem("Sample/Check")] public static void Check() { foreach (var path in AssetDatabase.FindAssets("t:Scene").Select(AssetDatabase.GUIDToAssetPath)) { Debug.Log(IsReadOnlyScene(path) ? $"ReadOnly Scene: {path}" : $"Editable Scene: {path}"); } } private static bool IsReadOnlyScene(string path) { var packageInfo = PackageInfo.FindForAssetPath(path); // Assets以下はnullが返ってくる if (packageInfo == null) { return false; } if (packageInfo.source == PackageSource.Local) { return false; } if (packageInfo.source == PackageSource.Embedded) { return false; } return true; } }