【Unity】【UI Toolkit】Painter2Dの描画結果をVectorImage型のアセットとして保存&読み込む

UnityのUI ToolkitでPainter2Dの描画結果をVectorImage型のアセットとして保存&読み込む方法についてまとめました。

VectorImageとは?

VectorImageとはUI Toolkitで定義されている、ベクターグラフィックスを表現するクラスです。
これはScriptableObjectなのでアセットとして永続化でき、また保存したアセットをUI Toolkitで画像のように扱うことができます。

実際にUI BuilderでVisual ElementのInspectorを見ると、BackgroundのImageをVectorに切り替えられることを確認できます。

Background Image

Painter2Dには、描画結果をこのVectorImageに保存する機能があります。
本記事ではこの機能についてまとめます。

Painter2Dの描画結果をVectorImageに保存する

それでは実際にPainter2Dによる描画結果をVectorImageに保存してみます。

using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class Example
{
    [MenuItem("Assets/Create/BezierCurveImage")]
    public static void DrawBezierCurveImage()
    {
        using var painter = new Painter2D(); // 最後にDisposeする必要があるのでusing

        painter.strokeColor = Color.red;
        painter.lineWidth = 10;
        painter.lineCap = LineCap.Round;
        painter.BeginPath();

        // (50, 300)を始点、(400,50)を終点、(225, 300)と(225,50)を制御点とする3次ベジェ曲線を引く
        var startPoint = new Vector2(50, 300);
        var endPoint = new Vector2(400, 50);
        var controlPoint1 = new Vector2(225, 300);
        var controlPoint2 = new Vector2(225, 50);
        painter.MoveTo(startPoint);
        painter.BezierCurveTo(controlPoint1, controlPoint2, endPoint);
        painter.Stroke();

        // VectorImageを作成する
        var vectorImage = ScriptableObject.CreateInstance<VectorImage>();
        painter.SaveToVectorImage(vectorImage);

        // activeObjectのあたりにアセットを作成する
        var activeObject = Selection.activeObject;
        var folderPath = "Assets";
        if (activeObject != null)
        {
            folderPath = AssetDatabase.GetAssetPath(activeObject.GetInstanceID());
            if (!AssetDatabase.IsValidFolder(folderPath))
                folderPath = Path.GetDirectoryName(folderPath);
        }

        var assetPath = folderPath + "/BezierCurve.asset";
        assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
        AssetDatabase.CreateAsset(vectorImage, assetPath);
        AssetDatabase.SaveAssets();
    }
}

説明はコメントに書いた通りです。
以下の記事で作成したようなベジェ曲線をVectorImageに書き出しています。

light11.hatenadiary.com

動作確認

Assets > Create > BezierCurveImageから上記のコードを実行すると、下図のようなアセットが生成されます。
Inspector を見ると頂点情報の配列が保持されていることを確認できます。

Inspector

次にこれをVisual Elementの背景として使ってみます。
UI Builderで適当なVisual Elementを作成し、Background.ImageをVectorに切り替えてからこのアセットを設定すると、以下の結果が得られます。

結果

保存したVectorImageを表示できていることを確認できました。