概要

本記事はCluster,Inc. Advent Calendar 2017の1日目の記事です。

プロジェクトの一部だけ切り取ってUnityPackageとして配信したいという状況があり、最初はこんな感じのビルド用のスクリプトを書いてメンテしていました。

[MenuItem("Tools/Export Unitypackage")]
public void Export()
{
    var assets = new[]
    {
        "Assets/Hoge.asset",
        "Assets/Huga.asset",
        "Assets/Hoo.asset",
        "Assets/Bar.asset",
    };
    var exportPath = "Build/Hoge.unitypackage";

    AssetDatabase.ExportPackage(
        assets,
        exportPath,
        ExportPackageOptions.IncludeDependencies | ExportPackageOptions.Recurse |
        ExportPackageOptions.IncludeLibraryAssets);
}

しかし、絶対パスでスクリプトを指定している箇所のメンテナンスが大変だったため、どうにかできないか考え、GUIDでアセットを保持して自動で書き出してくれるエディタ拡張を作りました。

コード

UnityPackageScriptableObject

using UnityEngine;

[CreateAssetMenu(fileName = "UnityPackageScriptableObject", menuName = "ScriptableObject/UnityPackage")]
public class UnityPackageScriptableObject : ScriptableObject
{
    [SerializeField] Object[] objects;

    public Object[] Files
    {
        get { return objects; }
    }
}

UnityPackageScriptableObjectEditor

using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(UnityPackageScriptableObject))]
public class UnityPackageScriptableObjectEditor : UnityEditor.Editor
{
    public override void OnInspectorGUI()
    {
        var targetPackage = (UnityPackageScriptableObject) target;
        base.OnInspectorGUI();

        if (!GUILayout.Button("Export unityPackage"))
        {
            return;
        }

        const string ext = "unitypackage";
        var path = EditorUtility.SaveFilePanel("Export unitypackage",
            Path.GetDirectoryName(AssetDatabase.GetAssetPath(targetPackage)),
            targetPackage.name + "." + ext, ext);

        if (!string.IsNullOrEmpty(path))
        {
            Export(targetPackage, path);
        }
    }

    public static void Export(UnityPackageScriptableObject package, string path)
    {
        EditorUtility.DisplayProgressBar("Exportiong package", "Exporting package", 0.5f);

        AssetDatabase.ExportPackage(
            package.Files.Select(AssetDatabase.GetAssetPath).ToArray(),
            path,
            ExportPackageOptions.IncludeDependencies | ExportPackageOptions.Recurse |
            ExportPackageOptions.IncludeLibraryAssets);
        EditorUtility.ClearProgressBar();
    }
}

使い方

Create -> ScriptableObject -> UnityPackageからScriptableObjectを作り、エクスポートしたいファイルを選びます。
フォルダを指定すると、そのフォルダ以下の全てのファイルがビルドに含まれます。

SnapCrab_NoName_2017-12-1_22-18-59_No-00.png

Export UnityPackageをクリックし、出力したいディレクトリを選ぶとUnityPackageが出力されます。
SnapCrab_NoName_2017-12-1_22-19-27_No-00.png

SnapCrab_NoName_2017-12-1_22-20-1_No-00.png