7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity(C#)】Particleの粒子を一つだけ出してそのポジションを取得する方法

Last updated at Posted at 2019-04-30

##Particle
Particleに関する知識が浅かったので少し沼にはまりました。

同じ苦しみを味わう人がいなくなることを願って書きます。

Particleはパラメーターが多いので
Unityを触り初めたばかりの頃は見てるだけで吐き気がしました。

とはいえ、上手く使えばとても便利なのは明白なのでマスターしといて損はないです。

##経緯
Unityで花火を作っていたのですが、音が耳元で鳴ることに違和を感じました。

そこで、

①花火が打ちあがった先のポジションを取得
②AudioSource付きオブジェクトを取得した位置に移動
③AudioSourceから音源を再生

という流れならいけるのでは?と思い試しました。

##花火
Particleを使った花火の作り方はこちらをご覧ください→花火

非常にわかりやすくまとめられているので小一時間でいい感じのものが完成します。

##Particleの粒子

今回の作り方は簡潔にまとめると
①花火の種が1つ打ちあがる(Particleの粒子1つ)
②花火の種が消える
③花火のParticleが広がる
という構成です。

ここで一つ沼にはまる要因がありまして、
花火の種がParticle粒子であるため、普通のゲームオブジェクトのように
ゲームオブジェクト名.transform.positionでポジションを取得できないという点です。

なので、普段のポジションの取得の仕方に比べ、遠回りして取得しなければなりません。

##Particle粒子のポジション取得方法

AudioSource付きゲームオブジェクトにアタッチ
    //花火の種のParticleSystem
    [SerializeField]
    ParticleSystem _particleSystem;

    ParticleSystem.Particle[] particles;

    int particleNum;

    void Start()
    {
        particles = new ParticleSystem.Particle[_particleSystem.emission.burstCount];
    }

    void Update()
    {
        //パーティクルの粒子が存在しているか確認
        if (_particleSystem.particleCount > 0)
        {
            particleNum = _particleSystem.GetParticles(particles);
            
            Vector3 particleSeedPosition = particles[0].position;

            this.gameObject.transform.position = particleSeedPosition;
        }
        else if (particleNum > 0 && _particleSystem.particleCount == 0)
        {
            //音源再生の処理
            particleNum--;
            AudioSource audioSource = this.gameObject.GetComponent<AudioSource>();
            audioSource.Play();
        }
    }

まずParticleSystem.Particleの中に取得したい粒子を全部入れてしまいます。
今回は一つしか出ない設定なので1と直接書いてしまっても問題ないかと思います。
burstCount.png
パラメーターから粒子の数を取得したい場合は
上の画像のCountの下の数字を取得してくればいいので
配列初期化時の要素数に_particleSystem.emission.burstCountを与えてあげれば可能です。

あとは_particleSystem.GetParticles(particles)とすることで
指定したParticleSystem内の粒子を全て取得することができます。

Vector3 particleSeedPosition = particles[0].position;

最後にparticlesのindexに先頭である0を指定して
粒子のポジション取得が完了です。

##GetParticles
スクリプトリファレンスにも記述ありましたが、
GetParticlesは現時点で生存しているParticleの粒子を取得するので、
Start内で呼び出してしまうとまだ存在していない粒子に対してGet(取得)してしまうことになり、
うまくいきませんでした。

##デモ

ParticleAudioSourceAdd.gif

AudioSourceが一緒に移動しているのがわかるかと思います。

前例が少ない、
エラーが出ない、
などなど、深い沼だった...

この沼から出れた瞬間の快感、病みつきになりますね。

7
4
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
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?