今回は、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 件のコメント:
コメントを投稿