概要
攻撃エフェクトや着地の砂埃といった単発パーティクルを色々な場所で発生させたいとき、発生者毎に ParticleSystem を用意しても良いですが、多少処理負荷が高くなります。
そこで、単発パーティクルを色々な場所に移動して再利用できるParticle Managerを作りました。
留意点
ParticleManager では、ParticleSystem に AudioSource を取り付けて、パーティクルと一緒に効果音を再生する実装方法が利用できません。その解決法として SEManager v2 を用意しました。
パーティクルの登録は AssetReferenceT<GameObject> で行うので、Addressables
のインポートが必要です。
パーティクルの登録時、playOnAwake は無効に変更されます。また、SimulationSpace は World に変更されます。
Task を使用しています。WebGLで扱う際は UniTask をインポートして Task を UniTask に置き換えてください。
Addressables の参照カウンタを参考にして、使用数カウンタというものを実装しています。使用数カウンタはAddOrIncrementAsync()
で増加し、RemoveOrDecrement()
で減少します。使用数カウンタが0になったら解放と破壊が行われます。
コード
利用方法
[SerializeField] AssetReferenceT<GameObject> particleRef;
private async void Start()
{
await ParticleManager.AddOrIncrementAsync(particleRef);
ParticleManager.Get(particleRef, transform.position, transform.rotation).Play();
}
private void OnDestroy()
{
ParticleManager.RemoveOrDecrement(particleRef);
}
関数紹介
関数名 | 説明 |
---|---|
AddOrIncrement() | パーティクルを読み込み、登録します。既に登録されている際は、使用数カウンタをインクリメントします。 |
Get() | 登録されているパーティクルを取得します。 |
GetAll() | 登録されているパーティクルを全て取得します。 |
RemoveOrDecrement() | 使用数カウンタをデクリメントします。カウンタが0になったらパーティクルを解放・破壊します。 |
Contains() | パーティクルの登録を確認します。 |
ForceRemove() | 強制的にパーティクルを解放・破壊します。 |
RemoveAll() | 全てのパーティクルを強制的に解放・破壊します。インゲーム終了時などに呼べば解放忘れが有っても解放できます。 |
UniRx で解放忘れを防ぐ
#define USE_UNIRX
を有効にするとAddOrIncrement()
の第2引数に Component を設定できるようになります。設定した Component が破壊されたとき RemoveOrDecrement() が呼ばれるようになるので、解放忘れを防げます(UniRx のインポートが必要です)。
[SerializeField] AssetReferenceT<GameObject> particleRef;
private async void Start()
{
await ParticleManager.AddOrIncrementAsync(particleRef, this);
ParticleManager.Get(particleRef, transform.position, transform.rotation).Play();
}
// RemoveOrDecrement() は不要