初めに
Unityの機能、Visual Effect Graphを使うとノードベースのエディタでエフェクトを作成することができます。GPUで処理されるので大量のパーティクルを扱うことができます。
AudioSourceで流してる音声に合わせて変化するエフェクトを作成したかったのでVFXGraphのPropertyに渡すスクリプトを作成しました。
スクリプト
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軸に並べたパーティクルと円状に並べたパーティクルを動かします。
使い方
GameObjectに上のスクリプトとAudioSourceコンポーネントとVFXGraphを適用します。
再生すると音楽に合わせてパーティクルも動きます。(UnityRecorderで録画してGIFを生成したら1fpsしかでませんでした)