Version: Unity 6.0 (6000.0)
言語 : 日本語
アセットデータベースの更新
プリセット

アセットデータベースワークフローのカスタマイズ

AssetDatabase クラスを使用してアセットパイプラインをカスタマイズしたり、独自のスクリプトでアセットにアクセス、ロード、作成、操作するためのツールを作成したりすることで、エディターの動作を拡張することができます。このクラスは Editor クラスであるため、スタンドアロンビルドではランタイムにその機能は使用できません。

アセットワークフローのカスタマイズ

AssetDatabase クラスには多数のメソッドがあります。これらのメソッドは、Unity エディターが行うのと全く同じようにアセットにアクセスして操作を行うことができます。アセットの作成、インポート、削除、コピー、移動、ロード、保存、アセットデータベースの検索が可能です。

つまり、Unity の Editor スクリプトEditor ウィンドウのカスタマイズを使用して、簡単な調整から強力なツールやプロジェクトのアセットワークフローのカスタマイズまで、あらゆるものを作成できます。

簡単な例については、AssetDatabase.ForceReserializeAssets メソッドのドキュメントを参照してください。これは、Unity の新しいバージョンにプロジェクトをアップグレードするときに、特定のアセットバンドルをアップグレードする方法をより良くコントロールできるように、エディターにメニュー項目を追加する方法を示しています。

利用可能なメソッドの全リストと各メソッドのドキュメントは、AssetDatabase のスクリプティング API のページを参照してください。

アセットオブジェクト

スクリプティングの観点から考えると、Unity が “アセット” とみなすものは、Project ウィンドウに表示されるものとは少し異なります。プロジェクトの Assets フォルダーに配置するファイルはアセットのソースファイルですが、Unity エディターが扱うアセットオブジェクトとは概念的に異なります。Unity はアセットファイルをインポートすると、それを処理してインポート結果、つまり UnityEngine.Object から派生したシリアライズされた C# オブジェクトを生成します。スクリプトの観点から見ると、Unity エディターでスクリプトを書くときにアクセスするアセットは、このインポートの成果物です。

例えば、JPEG や PNG の画像ファイルのようなバイナリファイルから始まるアセットは、UnityEngine.Object を特殊化した C# オブジェクトに変換されます。JPEG や PNG ファイルの場合、これらは Texture クラスのシリアル化されたインスタンスに変換され、UnityEngine.Object から継承されます。シリアル化されたオブジェクトデータは、Library フォルダーにアーティファクトとして保存されます。つまり、スクリプトで Texture アセットにアクセスするときは、元の JPEG や PNG ファイルにアクセスしているのではなく、元の画像ファイルをインポートしたときに生成された C# Texture オブジェクトのシリアル化されたバージョンにアクセスしています。インポート処理中に Unity が作成する .meta ファイルは、元のアセットファイルの隣に保存され、アセットのインポート設定と、Unity がアセットデータベースのアーティファクトを含む元のアセットファイルと接続するための GUID を含んでいます。

アセットをインポートすると、Unity は Assets フォルダーに .meta ファイルを作成し、Library フォルダーにアーティファクトファイルを作成する
アセットをインポートすると、Unity は Assets フォルダーに .meta ファイルを作成し、Library フォルダーにアーティファクトファイルを作成する

アセットファイルとアーティファクトファイルの内部

.prefab.scene.asset.mat など、Unity 自体が作成するアセットファイルには、そのソースファイルにすでにシリアル化されたデータが含まれているものがあります。そのため、Unity が生成してキャッシュするアーティファクトファイルは、ソースファイルに非常によく似ています。これらのソースファイル、例えばプロジェクトの Assets フォルダー内の .mat マテリアルファイルは、人間が読むことができます (ただし Asset Serialization モードがデフォルト設定の Force Text に設定されている場合)。これは、通常は人間が読むことができない、テクスチャやオーディオなどの外部ソースからインポートされたバイナリアアセットファイルとは対照的です。

アセットファイルは複数のシリアル化されたオブジェクトを含むことが可能で、AssetDatabase メソッドでスクリプトを作成する際には、これらのオブジェクトをそれぞれ “アセット” とみなすことができます。例えば、.prefab アセットファイルは、複数のコンポーネントがアタッチされたシリアル化されたゲームオブジェクトを含むことができます。これらの各コンポーネントもアセットファイル内のオブジェクトとしてシリアル化されているため、AssetDatabase メソッドを使用してプレハブアセットのコンテンツにアクセスする場合、アセットファイル内のコンポーネントオブジェクトはサブアセットとみなされます (以下で詳しく説明します)。

インポート処理中に生成されたシリアル化されたオブジェクトはアーティファクトと呼ばれます。Unity はこれらを、プロジェクトの Library フォルダーにあるインポートされたアーティファクトの Asset Database のキャッシュに保存します。Unity は、プロジェクトに保存されているインポーターの設定とプロジェクトの設定を使用して、ソースアセットからそれらをいつでも再生成できるため、それらはキャッシュデータとして扱われます。

Import Activity ウィンドウを使用すると、プロジェクト内のアセットに対して生成されたアーティファクトを確認できます。このウィンドウでは、Unity が生成した特定のキャッシュされたアーティファクトファイルのほか、インポートがいつ行われたか、どれくらいの時間がかかったかなどの有用な情報が表示されます。

各アーティファクトのファイル名は、ファイル拡張子のない一意のハッシュ (GUID) です。Unity はこれらのファイルをサブフォルダーに分け、各サブフォルダーにはアーティファクトファイル名の最初の 2 文字に一致する名前を与えます。

これらのアーティファクトファイルにはバイナリデータが含まれており、人間が読めるようには設計されていません。これらのファイルにはアセットデータベースで使用されるデータが含まれていることを理解しておくと便利ですが、Unity での作業中にこれらのファイルを直接表示、編集、使用する必要はありません。代わりに、AssetDatabase クラスはエディター内でアセットを扱うために必要なメソッドを提供します。

主なアセットとサブアセット

Unity は同じアセットファイル内に複数のシリアル化されたオブジェクトを格納できるため、Unity にはすべてのアセットファイル内でメインアセットという概念があります。Unity がマテリアルなどの単一のアセットを含むアセットファイルを作成する場合、メインアセットは常にその単一のアセットです。複数のシリアル化されたアセットオブジェクトを含む他のタイプの場合、SetMainObject メソッドで特に指定しない限り、常に、メインアセットはファイルに加えられた最初のアセットになります。

サブアセットが特定のタイプである場合、エディターの Project ウィンドウにサブアセットが表示されることがあります。例えば、“Space Frigate ”モデルを含むこの FBX アセットファイルを Project ウィンドウで見てみると、そのビューが展開され、サブアセットとしてマテリアルとメッシュを持っていることがわかります。

Project ウィンドウに表示された FBX アセットファイル。2 つのサブアセット (マテリアルとメッシュ) が表示されている
Project ウィンドウに表示された FBX アセットファイル。2 つのサブアセット (マテリアルとメッシュ) が表示されている

アセットには、このように Project ウィンドウに表示されないサブアセットタイプもあります。例えば、上記の “Space Frigate” アセットファイルには実際に、Project ウィンドウに表示されている 2 つのサブアセットよりも多くのものが含まれています。以下のスクリプトのように、AssetDatabase メソッドを使用してアセットファイルにアクセスすると、実際のアセット数を確認できます。

using UnityEngine;
using UnityEditor;

public class Example : MonoBehaviour
{
    [MenuItem("AssetDatabase/InspectAssets")]

    private static void InspectAssets()
    {
        Object[] data = AssetDatabase.LoadAllAssetsAtPath("Assets/Space Frigate.fbx");

        Debug.Log(data.Length + " Assets");
        foreach (Object o in data)
        {
            Debug.Log(o);
        }
    }
}

この場合、インポートされたシリアル化されたファイルには 6 つのアセットが含まれていることが出力されます。

6 Assets
Space Frigate (UnityEngine.GameObject)
space_frigate_0 (UnityEngine.Material)
space_frigate_0 (UnityEngine.Mesh)
Space Frigate (UnityEngine.Transform)
Space Frigate (UnityEngine.MeshRenderer)
Space Frigate (UnityEngine.MeshFilter)

これは、ゲームオブジェクト、マテリアル、メッシュデータそのもの、そして Unity がインポート処理中にゲームオブジェクトに自動的に加えた各コンポーネント (Transform、MeshFilter、MeshRenderer) が、それぞれ別のシリアル化されたオブジェクトとされるためです。したがって、これらはアセットファイルのサブアセットであり、Asset Database API を考える限り、それぞれ別のアセットです。

アセットインポートの順序

AssetDatabase クラスを使用してスクリプトを作成する場合、Unity のインポート処理の順序がスクリプトにどのような影響を与えるかを理解することが重要です。これを理解しておかないと、予期しない結果になることがあります。順序は以下のとおりです。

  1. スクリプトアセット (.cs、.dll、.asmdef ファイル) のインポート
  2. Compilation
  3. ドメインのリロード
  4. InitializeOnLoad コールバック
  5. 他のすべてのアセットのインポート

エディターは、プロジェクトにカスタムのアセットのポストプロセッサースクリプトインポーターがあるかどうかを知る必要があるため、スクリプトは常に、他のすべての通常のアセットより先にインポートされ、コンパイルされます。これにより、エディターは、スクリプト以外の残りのアセットをインポートするときに、新規または変更されたインポーターやポストプロセッサーを使用します。

InitializeOnLoad コールバックは、プロジェクトの起動時やスクリプトの変更時にコードを実行するためによく使用されます。上記のリストにあるように、このコールバックは Unity がドメインをリロードした後、アセットのインポートを開始する前に実行されます。つまり、InitializeOnLoad コールバックを使用してアセットにアクセスする場合、コードは現在のアセットインポートサイクルが完了する前に実行されます。特に以下の点に注意してください。

  • アセットが初めてインポートされる場合、AssetDatabase.LoadAssetAtPath、AssetDatabase.FindAssets、Shader.Find、Resources.Load などのメソッドは、これらのアセットがまだインポートされていないため、NULL を返します。

  • 少なくとも一度インポートしたアセットについては、AssetDatabase.LoadAssetAtPath、AssetDatabase.FindAssets、Shader.Find、Resources.Load などのメソッドは、ドメインのリロード前に変更された場合は以前の (古い) バージョンのアセットを返します。これは、ドメインのリロードが通常のアセットインポートフェーズの前に発生するためです。

スクリプト形式のインポーター、アセットプリプロセッサー、およびアセットポストプロセッサーを作成する場合は、他の特定のアセットが特定の順序に従ってすでにインポートされていることを前提としてコードを作成しないでください。Unity はインポートするとき、アセットをタイプ別にキューにグループ化します。タイプはあらかじめ定義されている順序でインポートされますが、ScriptedImporter.GatherDependenciesFromSourceFile を使用しない限り、同じタイプのキュー内のアセットは任意の順序でインポートされます。GatherDependenciesFromSourceFile を使用すると、アセット間の依存関係も作成されるため、1 つのアセットが変更されると、それに依存するもうひとつのアセットが再インポートされます。

アセットデータベースの更新
プリセット