ゴイサギ日記

東京でエンジニアとして頑張って何とか生きてます。。ゆる~く更新していきます

【Unity】IParticleSystemJob を使ってみた

今回は IParticleSystemJob を使ってみました。
確認バージョンは Unity2019.1.0f2 です。

はじめに

IParticleSystemJobとは、昨年くらいから何かと話題の「JobSystem」を使ってパーティクルデータの操作が出来るものです。試験的な機能なのでFix版までは今後も変更が入ってくる可能性がありますが・・

2021/05/02 追記
Unity2019.3から正式版として UnityEngine.ParticleSystemJobs に移行

実装

最もシンプルな実装はこちらにまとまっています。今回は折角なので CustomData モジュールで定義したカーブアニメーションを IParticleSystemJob から取得してカラー変更する処理を実装してみます。

以下コードです。

using System;
using System.Collections;
using System.Collections.Generic;

using UnityEngine;
using UnityEngine.Experimental.ParticleSystemJobs;

public class SampleParticle : MonoBehaviour
{
    void Awake()
    {
        ParticleSystem ps = GetComponent<ParticleSystem>();
        ps.SetJob( new ParticleJob());
    }

    struct ParticleJob : IParticleSystemJob
    {
        public void ProcessParticleSystem( ParticleSystemJobData jobData )
        {
            Color customColor = Color.white;

            var startColors = jobData.startColors;
            var customDatas = jobData.customData1;
            for( int idx=0 ; idx < startColors.Length ; idx++ )
            {
                customColor.r = customDatas.x[ idx ];
                customColor.g = customDatas.y[ idx ];
                customColor.b = customDatas.z[ idx ];
                customColor.a = customDatas.w[ idx ];
                startColors[ idx ] = customColor;
            }
        }
    }
} 

殆ど説明が必要ない短さですね(^^;)
1. IParticleSystemJob を継承した構造体を定義
2. ProcessParticleSystem() を定義
3. 引数の ParticleSystemJobData に Active状態のパーティクルデータが入ってくるので必要な更新を記述
4. 対象ParticleSystem の SetJob() にジョブを設定

実行画面はこんな感じです。
f:id:aki517:20190427221558g:plain

Profiler で確認すると Worker Threadで処理されてます。 f:id:aki517:20190427221207p:plain

Worker Thread と Main Threadで比較が出来るプロジェクトをgithubに上げてあります。

github.com

まとめ

パーティクルデータのコピーなしでデータ操作出来るのは便利です。ParticleSystemのGetParticles/SetParticles は呼び出しコストが高いのでそこが無くなるだけでも恩恵はあるかなと・・

あとフォーラムにも書いてましたが将来的に Trigger/Collisionモジュールの衝突検知用コールバックが IParticleSystem に追加されるとゲームロジックに合わせた処理を入れたりと実装の幅が広がりそうですね。

ただ、ゲームロジックが絡んでこない処理なら Custom Vertex Stream を使ってシェーダ側で処理をした方が速度が出ると思います。

参考

Unity - Particle System C# Job System support - Unity Forum

Particle System Improvements (2019.1) - Google ドキュメント