【Unity(C#)】ParticleSystemのややこしいところまとめ(の予定)

##ParticleSystem(シュリケン)
Unityの**超便利機能**です。
誰でもお手軽にエフェクトの作成が行えます。

**しかし！一歩踏み込んでScriptで変更しようと思うと一手間も二手間もかかります！**

##(の予定)？？
Particleを一度利用したことがある人には理解して頂けるかと思いますが、
**パラメーターの数が半端じゃなく多い**です。(私のような初心者にとっては)

なので、私が利用しようとして詰まったとこを随時更新していきます。
みなさんの方でも**こんなの見つけられっこないよ！ってので半日つぶした**なんてエピソードをお持ちでしたら
編集リクエストやコメントでの支援をお願いします。


ぜひ、手を取り合ってParticleを攻略しましょう。(他力本願)


##MainModule

Durationの変更はParticleSystemのプレイ中には不可のようです。
![duration.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/83184148-1e2c-df33-0d34-0cc35c6d3d79.png)


```C#:MainModuleをいろいろ変更するサンプル
using UnityEngine;

public class ParticleTest : MonoBehaviour
{
    float _durationTimeValue = 5;
    float _startLifeTimeValue=3;

    ParticleSystem _particleSystem;
    ParticleSystem.MainModule _mainModule;
    ParticleSystem.MinMaxCurve _minMaxCurve;
    AnimationCurve _animationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
   
    void Start()
    {
        _particleSystem = this.gameObject.GetComponent<ParticleSystem>();
        _mainModule = _particleSystem.main;
        _minMaxCurve = _mainModule.startLifetime;
        _animationCurve = _mainModule.startLifetime.curve;

        //Durationの変更はParticleSystemのプレイ中には不可のようです
        //_mainModule.duration = _durationTimeValue;

        //Loopのオンオフ
        _mainModule.loop = false;

        //StartLifeTimeの値の変更(Constantの場合)
        _minMaxCurve = _startLifeTimeValue;
        _mainModule.startLifetime = _minMaxCurve;

        //StartLifeTimeのモードの変更(Constant→Curve)
        ParticleSystemCurveMode particleSystemCurveMode = ParticleSystemCurveMode.Curve;
        _minMaxCurve.mode = particleSystemCurveMode;

        //StartLifeTimeの値の変更(Curveの場合)
        _minMaxCurve.curve = _animationCurve;
        _mainModule.startLifetime = _minMaxCurve;

        //2020/08/18 追記
        //StartColorの変更
        _mainModule.startColor = Color.red;
    }
}
```
##Emission
これけっこう頻繁に使いますよね。(私だけ?)
任意の処理に応じてパーティクルの量を調節できるのは便利です。

```C#:Emissionをだんだん減らして消滅したように見せるサンプル
using UnityEngine;

public class ParticleTest : MonoBehaviour
{
    [SerializeField]
    float deleteSpeed = 0.01f;

    ParticleSystem _ParticleSystem;
    ParticleSystem.EmissionModule _EmissionModule;
    ParticleSystem.MinMaxCurve _MinMaxCurve;

    void Start()
    {
        _ParticleSystem = this.gameObject.GetComponent<ParticleSystem>();
        _EmissionModule = _ParticleSystem.emission;
        _MinMaxCurve = _EmissionModule.rateOverTime;
    }

    void Update()
    {
        //だんだんと消滅させる
        _MinMaxCurve.constant -= deleteSpeed;
        _EmissionModule.rateOverTime = _MinMaxCurve;
    }
}
```
![PSE.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/c48f0bf2-74bc-484b-824b-6c1caabb7879.gif)

##粒子のヒットした場所を取得

このサンプル内では粒子は一つしか存在しない状態(Max Particles = 1)にしてあります。

```C#:粒子のヒットした場所にキューブが出現するサンプル
using System.Collections.Generic;
using UnityEngine;

public class ParticleHit : MonoBehaviour
{
    [SerializeField]
    GameObject obj;

    List<ParticleCollisionEvent> particleCollisionEventList = new List<ParticleCollisionEvent>();

    ParticleSystem _ParticleSystem;

    void Start()
    {
        _ParticleSystem = this.gameObject.GetComponent<ParticleSystem>();
    }

    //パーティクルの当たった箇所でオブジェクト出現
    void OnParticleCollision(GameObject other)
    {
        _ParticleSystem.GetCollisionEvents(other, particleCollisionEventList);

        Vector3 collisionHitPos = particleCollisionEventList[0].intersection;

        Instantiate(obj,collisionHitPos,Quaternion.identity);
    }
}
```
![PSC.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/2743a854-e5e9-94c4-4f8c-d2bf5e4e41c1.gif)



今のところ氷山の一角という表現も適さないボリュームですが、よく使い、よく忘れるので記録しときます。

##参考リンク
[ParticleのstartColorをスクリプトで変更する](http://am1tanaka.hatenablog.com/entry/2017/07/01/183619)