概要
「大量のパーティクルを表示したい…」「爆発や魔法のエフェクトを作りたい…」「もっと高度な表現がしたい…」
ゲーム開発では、このようなビジュアルエフェクトの課題に直面することがあります。VFX Graph は、Unity公式のビジュアルエフェクト作成ツールです。ノードベースのビジュアルロジックでエフェクトを作成し、GPUベースのパーティクルシステムで大量のパーティクルを高パフォーマンスで表示できます。
従来のParticle Systemとの違い
Particle System(Shuriken)
- CPUベースのパーティクルシステム
- Unity初期から存在
- インスペクターで設定
- モジュール式の設計
- 衝突検出が可能
- 設定が簡単、情報が豊富
- 処理負荷が高くなりがち(数千個が限 界)
VFX Graph
- GPUベースのパーティクルシステム
- ノードベースのグラフで設定
- 大量のパーティクルを表示可能(数百万個も可能)
- 衝突検出は限定的
- 学習コストが高い
- Shader Graphと統合可能
- より高度な表現が可能
パフォーマンス比較
| シナリオ | 推奨システム |
|---|---|
| 大量のパーティクルを1つのシステムで表示 | VFX Graph(圧倒的に軽い) |
| 多数の異なるエフェクトを同時に表示 | Particle System(軽い場合がある) |
| 同じエフェクトを大量に配置 | VFX Graph(インスタンシングで軽い) |
使い分けのポイント
VFX Graphを使うべき場合
- 大量のパーティクルを表示したい(爆発、炎、煙、魔法など)
- 高度な表現が必要
- Shader Graphと連携したい
- 同じエフェクトを大量に配置する
Particle Systemを使うべき場合
- 衝突検出が必要
- 素早く設定したい
- シンプルなエフェクトで十分
- 多数の異なるエフェクトを同時に表示する
VFX Graphの基本構造
2つの要素
VFX Graphは2つの要素で構成されます。
| 要素 | 説明 |
|---|---|
| Visual Effectコンポーネント | GameObjectにアタッチ |
| Visual Effect Asset | エフェクトの設定を格納 |
4つのコンテキストノード
VFX Graphのノードは 上から下 に向かってデータが流れます。
1. Spawnコンテキストノード
フレームごとの生成数を決定し、Initialize Particleに渡します。
- Constant Spawn Rate - 一定の割合でSpawnイベントを発行
- Burst - 一度に大量のパーティクルを生成
その他のSpawnブロック:
Periodic Burst(一定間隔でバースト)、Variable Spawn Rate(動的に変化する生成レート)なども利用可能です。
2. Initialize Particleコンテキストノード
パーティクルの初期化を行います。
- Capacity - 同時に表示できるパーティクルの最大数(下記目安参照)
プラットフォーム別Capacity目安:
| プラットフォーム | 実用的なCapacity目安 | 備考 |
|---|---|---|
| ハイエンドPC | 100万〜500万 | GPU性能に大きく依存 |
| ミドルレンジPC | 10万〜50万 | |
| コンソール | 10万〜100万 | プラットフォームによる |
| モバイル | 1万〜5万 | 発熱・バッテリーにも注意 |
Capacityの見積もり: Capacityは「最大同時存在数」です。生成レート×寿命で実際の表示数を見積もり、過剰に設定するとVRAMを無駄に消費します。
- Set LifeTime - パーティクルの寿命
- Set Position Shape - パーティクルの初期位置(形状から生成)
- Set Velocity - パーティクルの初期速度
3. Update Particleコンテキストノード
パーティクルの毎フレーム更新処理を行います。
- Gravity - 重力を適用
- Linear Drag - 抵抗を適用
- Force - 力を適用
- Collision - 衝突検出(限定的)
4. Output Particleコンテキストノード
パーティクルの最終的な描画設定を行います。
Outputの種類:
| Output | 用途 |
|---|---|
| Output Particle Quad | 板ポリゴン(最も一般的) |
| Output Particle Mesh | 3Dメッシュを使用 |
| Output Particle Strip | 軌跡・リボン表現 |
| Output Particle Point | ポイントスプライト |
主なブロック:
- Orient - パーティクルの向き(ビルボードなど)
- Set Size Over Life - 寿命に応じたサイズ変化
- Set Color Over Life - 寿命に応じた色変化
- Main Texture - 使用するテクスチャ
- Blend Mode - アルファブレンドの 設定
インストール方法
- Window > Package Manager を開く
- Unity Registryを選択
- Visual Effect Graphを選択
- Installボタンをクリック
URPプロジェクトでの追加設定
バージョン注記: URP 14以降(Unity 2023.1+)では、VFX Graphは特別な設定なしで動作します。以下はそれ以前のバージョン向けの手順です。
URPプロジェクトでは、URP Assetでの設定が必要な場合があります。
- URP Asset(Universal Render Pipeline Asset)を選択
- Renderer List から使用しているRendererを選択
- Renderer Features でVFX Graphが有効になっていることを確認
基本的な使い方
エフェクトの作成
- GameObject > Visual Effects > Visual Effect を選択
- Visual Effectコンポーネントがアタッチされたゲームオブジェクトが作成される
- Visual Effectコンポーネントの「New」ボタンをクリック
- テンプレートを選択(Simple Loop、Burst、Continuousなど)
- ファイル名を付けて保存
グラフの編集
- ProjectウィンドウのVisual Effect Assetをダブルクリック
- VFX Graphウィンドウが開く
- ノードを追加・編集してエフェクトをカスタマイズ
Learning Templatesの活用
Unity公式の学習用テンプレートを使って学習できます。
- Assets > Create > Visual Effects > Visual Effect Graph を選択
- Create New VFX Assetウィンドウで「Install Learning Templates」をクリック
- 様々なテンプレートが追加される
プログラムからの制御
イベントの送信
using UnityEngine;
using UnityEngine.VFX;
public class VFXController : MonoBehaviour
{
VisualEffect visualEffect;
void Start()
{
visualEffect = GetComponent<VisualEffect>();
}
public void Play()
{
// デフォルトイベント
visualEffect.SendEvent(VisualEffectAsset.PlayEventName); // OnPlay
}
public void Stop()
{
visualEffect.SendEvent(VisualEffectAsset.StopEventName); // OnStop
}
public void SendCustomEvent()
{
// カスタムイベント
visualEffect.SendEvent("CustomEventName");
}
}
高パフォーマンスな方法(IDを使用)
public static readonly int CustomEventID = Shader.PropertyToID("CustomEventName");
void SendEvent()
{
visualEffect.SendEvent(CustomEventID);
}
プロパティの設定
VFX GraphのBlackboardで定義したプロパティをスクリプトから設定できます。
// 各種プロパティの設定
visualEffect.SetFloat("SpawnRate", 100f);
visualEffect.SetVector3("EmitterPosition", transform.position);
visualEffect.SetTexture("MainTexture", myTexture);
visualEffect.SetGradient("ColorGradient", myGradient);
// プロパティの取得
float rate = visualEffect.GetFloat("SpawnRate");
// デバッグ: 現在のパーティクル数を確認
// aliveParticleCountはGPU Readbackで取得するため、
// 1〜2フレームの遅延があります。
// パーティクルにLifetimeが設定されていない 場合、
// すべてのパーティクルが永続的にaliveとなります。
int aliveCount = visualEffect.aliveParticleCount;
Exposed Property: Blackboardでプロパティを作成する際、Exposed にチェックを入れないとスクリプトからアクセスできません。
パフォーマンス: 頻繁に呼び出す場合は
Shader.PropertyToID()でIDを事前取得し、SetFloat(int id, float value)を使用してください。
パラメータ付きイベントの送信
VFXEventAttributeを使って、位置や色などのパラメータを動的に渡せます。
public void SpawnAtPosition(Vector3 position, Color color)
{
VFXEventAttribute eventAttribute = visualEffect.CreateVFXEventAttribute();
eventAttribute.SetVector3("position", position);
eventAttribute.SetVector4("color", new Vector4(color.r, color.g, color.b, color.a));
visualEffect.SendEvent("OnSpawn", eventAttribute);
}
VFX Graph側の設定: Initialize Particleコンテキストで
Get Source Attributeブロック(position、colorなど)を追加し、Eventから渡されたパラメータを受け取ります。
初期状態で停止させる方法
以下のいずれかの方法を使用します:
- Initial Event Nameを空に設定 - 自動再生を無効化
- Initial Event Nameに独自のイベント名を設定 - 手動でイベントを送信するまで開始しない
よくある使用例
大規模なパーティクルエフェクト
- 爆発、炎、煙
- 魔法エフェクト
- 雨、雪
- 星空、花火
環境エフェクト
- 霧