今回は、Unityの話。たぶん、ブログではそんな扱ってなかったね-。
定期的に音が鳴っているオブジェクトを破棄する場合、audio.Stop()使えばまあ音は止まるんだが、
音がブツっとなるのがちょっと嫌。
で、まあ、音量をフェードアウトさせてから破棄してみようと思った。(volume=0.0fとするだけでも十分という気もしないでもない。)
Audioクラス自体にはフェード機能とかそんなのないので、試しにコルーチンを使ってみる。
void OnHitItem() { Debug.Log("OnHitItem"); valid = false; // Stopと使うと音がぶつ切りになる場合があるため、音量をフェードアウトさせて対応 //audio.Stop(); // 子においておいたパーティクルのエフェクトを開始 ParticleSystem particleSystem = gameObject.GetComponentInChildren<particlesystem>(); if (particleSystem) { particleSystem.Play(); Debug.Log("Particle Start"); } // フェードアウトスタート StartCoroutine("Fadeout", 1.0f); Debug.Log("OnHitItem End"); } IEnumerator Fadeout( float duration ) { float currentTime = 0.0f; float waitTime = 0.02f; float firstVol = audio.volume; while (duration > currentTime) { currentTime += Time.fixedDeltaTime; audio.volume = Mathf.Clamp01(firstVol * (duration - currentTime) / duration); Debug.Log("Step:" + audio.volume); yield return new WaitForSeconds(waitTime); } // エフェクトが完全に終了していたらオブジェクト破棄 ParticleSystem particleSystem = gameObject.GetComponentInChildren<particlesystem>(); while (particleSystem.isPlaying) { yield return new WaitForSeconds(waitTime); } Destroy( gameObject ); Debug.Log("Destory"); } // (以下略
まあ、こんな感じかなー。
アイテムに接触時に、外からOnHitItemが呼ばれることを想定してる。
呼ばれると同時に、接触したことを知らせるパーティクル表現を入れつつ、音をコルーチンでフェードアウトする。
さらに、一応パーティクルによるエフェクトが終了していることを確認してからDestory
ただし、コルーチン使う場合は、StartCoroutine直後の
Debug.Log("OnHitItem End");
も即実行されてしまうので注意。つまり、
OnHitItem Particle Start Step: xx OnHitItem End Step: xx Step: xx ... Destory
こんな感じの実行順になる。はず。
追記:
こうしたほうが楽じゃね?こういうときに、Mathf.Lerpとか使うべきだよね。
while (duration > currentTime) { //audio.volume = Mathf.Clamp01(firstVol * (duration - currentTime) / duration); audio.volume = Mathf.Lerp( firstVol, 0.0f, currentTime/duration ); Debug.Log("Step:" + audio.volume); yield return new WaitForSeconds(waitTime); currentTime += waitTime; }
0 件のコメント:
コメントを投稿