0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】ParticleSystemからいらないアセット参照を消すEditor拡張を作った

Posted at

はじめに

UnityのParticleSystemでは使用したい機能(モジュール)を追加をし、モジュールによってはMeshやTextureを設定して使用することができます。

しかし、一度モジュールにチェックをいれ、Meshを登録した後にモジュールのチェックを外すとMeshのアセット参照は残ったままになります。
そのためパーティクルをロードする際に不必要なアセットも巻き込んでロードされます。
これを防ぐために必要のないアセット参照は消すEditor拡張を作りました。

ソースコード

仕組み

スクリプトで全プロパティをチェックして不要であれば消す…といった方法をできればよかったのですができなかったので各モジュールやEnumを設定した場合にアセットを設定できそうであればそれをif文でチェックしてNullを代入して消すといった方法で消してます。

1つのアセット参照を消す場合

例えばShapeモジュールの場合です。

image.png

ShapeがConeの時はTextureだけを入れることができます。
しかし、ShapeをMeshに変更すると

image.png

Meshの登録ができるようになります。

private void ClearShapeModuleProperties(ParticleSystem particleSystem)
{
    var shapeModule = particleSystem.shape;
    
    // shapeModuleが使用されていなかったら関係するアセット参照を消す
    if (!shapeModule.enabled)
    {
        shapeModule.texture = null;
        shapeModule.mesh = null;
        shapeModule.meshRenderer = null;
        shapeModule.skinnedMeshRenderer = null;
        shapeModule.sprite = null;
        shapeModule.spriteRenderer = null;
        return;
    }
    
    // 対応したMesh以外にアセット参照がある可能性があるので消す
    switch (shapeModule.shapeType)
    {
        case ParticleSystemShapeType.Mesh:
            shapeModule.meshRenderer = null;
            shapeModule.skinnedMeshRenderer = null;
            shapeModule.sprite = null;
            shapeModule.spriteRenderer = null;
            break;

        // 他にもパターンがあるが説明のために省略
        
        default:
            // どれにも一致しない場合はすべて除去
            shapeModule.mesh = null;
            shapeModule.meshRenderer = null;
            shapeModule.skinnedMeshRenderer = null;
            shapeModule.sprite = null;
            shapeModule.spriteRenderer = null;
            break;
    }
}

そのためこのようなコードを作成します。
まず、そもそもShapeモジュールを使用しないときはif (!shapeModule.enabled)の中ですべてのアセット参照にNullを入れます。
どんなアセット参照がこのモジュールにあるのかはモジュールのすべてのチェックマークやEnumをポチポチ切り替えて探します。

Shapeに設定されているモードがMeshの場合はcase ParticleSystemShapeType.Mesh:でMesh以外のアセット参照を消します。
Coneなどを設定されている場合はMeshすらいらないのでdefault:でMeshも含めて全部消します。

Listを消す場合

CollisionモジュールなどではListを持っています。

image.png

この場合もモジュールを使わない場合やTypeがPlanesではない場合は参照を持つ必要がないので消します。

// 全てのPlaneを消す
void RemoveAllPlane()
{
    var planeCount = collisionModule.planeCount;
    if (planeCount > 0)
    {
        for (int i = planeCount - 1; i >= 0; i--)
        {
            collisionModule.RemovePlane(i);
        }
    }
}

このようなメソッドを作り、for文では要素を後ろから消します。
後ろから消している理由は普通に消すとRemovePlaneではそのIndexのPlaneが消え、以降のPlaneが詰められるせいで全部消せなかったりしたため後ろから消します。

また、

void ClearAllPlanes()
{
    for (int i = 0; i < 6; i++)
    {
        collisionModule.SetPlane(i, null);
    }
}

をこのようにNullを直接代入した場合はすべてNullになるため参照は消えますがListの大きさが確保されたままになってしまったのでやめまs

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?