LoginSignup
3
1

More than 1 year has passed since last update.

UnityでWeb上のベクター画像(SVG)を表示する

Last updated at Posted at 2022-01-11

VectorGraphicsパッケージを使用すると、SVG画像をスプライトとして使用することができます(導入方法)。

image.png

手元にあるSVGをインポートするだけならこれで十分なのですが、
たとえば https://elix.jp/test/svg/cat.svg にあるSVGを使いたかったので、方法を調べてみました。

まずHierarchy上で

Create>EmptyObject

で空のオブジェクトを作り、下記のスクリプトをアタッチします

SVGFromWWW.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

using UnityEngine;
using UnityEngine.Networking;
using Unity.VectorGraphics;

public class SVGFromWWW : MonoBehaviour
{
    [SerializeField] string m_url = "";
    [SerializeField] SpriteRenderer m_sr = null;
    [SerializeField] MeshRenderer m_mr = null;

    void Start()
    {
        StartCoroutine(WWWCo(m_url));
    }

    // Update is called once per frame
    void Update()
    {
    }

    IEnumerator WWWCo(string _url)
    {
        UnityWebRequest request = UnityWebRequest.Get(_url);
        yield return request.SendWebRequest();

        if (request.downloadHandler.error!="")
        {
            Debug.Log(request.downloadHandler.error);
        }
        else
        {
            Debug.Log(request.downloadHandler.text);
            using (var reader = new StringReader(request.downloadHandler.text))
            {
                SVGParser.SceneInfo sceneInfo =  SVGParser.ImportSVG(reader);

                var geometry = VectorUtils.TessellateScene(sceneInfo.Scene, new VectorUtils.TessellationOptions
                {
                    StepDistance = 1f,
                    SamplingStepSize = 1f,
                    MaxCordDeviation = 0.5f,
                    MaxTanAngleDeviation = 0.1f
                });
                m_sr.sprite = VectorUtils.BuildSprite(geometry, 100, VectorUtils.Alignment.Center, Vector2.zero, 0,true);

                Material mat = new Material(Shader.Find("Unlit/Vector"));
                Texture2D tex = VectorUtils.RenderSpriteToTexture2D(m_sr.sprite, 1024, 1024, mat);
                tex.wrapMode = TextureWrapMode.Clamp;
                m_mr.material.mainTexture = tex;
            }
        }
    }
}

次に

Create>2DObject>Sprites>Square
Create>3DObject>Quad

でスプライトと平面オブジェクトを作り、m_sr および m_mr にセットします。

image.png

image.png

あとは目的のSVGのURLをセットして実行すると、読み込んだSVGがスプライトと平面オブジェクトに表示されます。
image.png

これをさらに2D Animationさせられないかと思ったのですが、さすがに無理でした(Skinning Editorの項目が出ない)。

解説、というほどではないのですが簡単に補足しておくと、SVG画像はXMLベースのテキストなので
yield return request.SendWebRequest();
でSVG画像をリクエストして返ってきたrequest.downloadHandler.textを使います。
これをスプライト化するにはVectorUtilsというヘルパー関数群のクラスを用います。
まずは

                var geometry = VectorUtils.TessellateScene(sceneInfo.Scene, new VectorUtils.TessellationOptions
                {
                    StepDistance = 1f,
                    SamplingStepSize = 1f,
                    MaxCordDeviation = 0.5f,
                    MaxTanAngleDeviation = 0.1f
                });

StepDistance SamplingStepSizeなどのパラメータで画像を構成する要素の細かさ(曲線の粗さ)を決め、要素に分割します。

次に

m_sr.sprite = VectorUtils.BuildSprite(geometry, 100, VectorUtils.Alignment.Center, Vector2.zero, 0,true);

でそれをスプライト化しています。
Quad(3DObject)に適用するためにはマテリアルにテクスチャを指定する必要があるので、

Texture2D tex = VectorUtils.RenderSpriteToTexture2D(m_sr.sprite, 1024, 1024, mat);

で作成したスプライトを1024x1024の画像としてテクスチャ化し、マテリアルのテクスチャとして指定しています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1