AudioSourceで再生されている音声をVisual Effect Graphで扱う

# 初めに
Unityの機能、Visual Effect Graphを使うとノードベースのエディタでエフェクトを作成することができます。GPUで処理されるので大量のパーティクルを扱うことができます。
AudioSourceで流してる音声に合わせて変化するエフェクトを作成したかったのでVFXGraphのPropertyに渡すスクリプトを作成しました。
# スクリプト
```C#
using UnityEngine;
using UnityEngine.VFX;

public class AudioWaveSample : MonoBehaviour
{
    [SerializeField]
    private int outputWaveLength = 1024;

    [SerializeField]
    private int outputSpectrumLength = 1024;

    private AudioSource audioSource;
    private VisualEffect visualEffect;
    // テクスチャの要素
    private Color[] outputColors;
    private Color[] outputSpectrumColors;
    // VFXGraphに渡すプロパティ
    private Texture2D outputMap;
    private Texture2D outputSpectrumMap;
    // 波形データ
    private float[] outputWave;
    private float[] outputSpectrum;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        visualEffect = GetComponent<VisualEffect>();

        outputWave = new float[outputWaveLength];
        outputSpectrum = new float[outputSpectrumLength];
        outputColors = new Color[outputWaveLength];
        outputSpectrumColors = new Color[outputSpectrumLength];

        // テクスチャの用意
        outputMap = new Texture2D(outputWaveLength, 1, TextureFormat.RFloat, false);
        outputMap.filterMode = FilterMode.Bilinear;
        outputMap.wrapMode = TextureWrapMode.Clamp;

        outputSpectrumMap = new Texture2D(outputSpectrumLength, 1, TextureFormat.RFloat, false);
        outputSpectrumMap.filterMode = FilterMode.Bilinear;
        outputSpectrumMap.wrapMode = TextureWrapMode.Clamp;

        // テクスチャとデータ長を渡す
        visualEffect.SetTexture("OutputWaveMap", outputMap);
        visualEffect.SetTexture("OutputSpectrumMap", outputSpectrumMap);
        visualEffect.SetUInt("WaveLength", (uint)outputWaveLength);
        visualEffect.SetUInt("SpectrumLength", (uint)outputSpectrumLength);
    }

    void Update()
    {
        // 音声波形を取得する
        audioSource.GetOutputData(outputWave, 0);

        for (var i = 0; i < outputWaveLength; i++)
        {
            outputColors[i].r = outputWave[i];
        }
        outputMap.SetPixels(outputColors);
        outputMap.Apply();

        // スペクトラムを取得する
        audioSource.GetSpectrumData(outputSpectrum, 0, FFTWindow.BlackmanHarris);
        
        for (var i = 0; i < outputSpectrumLength; i++)
        {
            outputSpectrumColors[i].r = outputSpectrum[i];
        }
        outputSpectrumMap.SetPixels(outputSpectrumColors);
        outputSpectrumMap.Apply();
    }
}

```

# VFXGraph
今回はx軸に並べたパーティクルと円状に並べたパーティクルを動かします。
![VFXGraphAndShaderPractice - AttributeMap - PC, Mac & Linux Standalone - Unity 2020.1.2f1 Personal [PREVIEW PACKAGES IN USE] _DX11_ 2021_02_09 23_31_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/067486c8-f8d3-6ec5-6865-2247c5ee7d95.png)
![VFXGraphAndShaderPractice - AttributeMap - PC, Mac & Linux Standalone - Unity 2020.1.2f1 Personal [PREVIEW PACKAGES IN USE] _DX11_ 2021_02_09 23_32_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/6ccfcd4f-7c13-5dad-c786-9df9328a457f.png)


# 使い方
GameObjectに上のスクリプトとAudioSourceコンポーネントとVFXGraphを適用します。
![VFXGraphAndShaderPractice - AttributeMap - PC, Mac & Linux Standalone - Unity 2020.1.2f1 Personal [PREVIEW PACKAGES IN USE] _DX11_ 2021_02_09 23_39_13 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/c7529025-f4ef-c21f-8aa7-a1df2f561513.png)

再生すると音楽に合わせてパーティクルも動きます:ok_hand:。(UnityRecorderで録画してGIFを生成したら1fpsしかでませんでした)
![gif_animation_001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/9e533a5b-3ca8-3235-4f4a-b3885d807ed1.gif)

# 参考
- https://qiita.com/aa_debdeb/items/373ed230a78ad1c6b195
- http://tips.hecomi.com/entry/2014/11/11/021147