まゆたまガジェット開発逆引き辞典

電子工作やプログラミングのHowtoを逆引き形式で掲載しています。作りたいモノを決めて学んでいくスタイル。プログラマではないので、コードの汚さはお許しを。参照していないものに関しては、コピペ改変まったく問いません

一定以上のボリュームのときに大きさが変わる

音量が一定以上になったときにキャラクターの表情を変えたいと思い、そのテストとしてやってみました。
一定以上のボリュームになったら、オブジェクトのサイズと色が変わります。
ただ実際に実装したいのが「表情」なので、サイズと色が変わったらそれを2秒保持する(=2秒次の処理を止める)ことを行なっています。
瞬間的に表情が変わり続けるのはどうかと思うので・・・

数秒後に処理を行う、など時間を扱う処理である「コルーチン」を使いましたが、力技なような気がしてます。

大きさの変化に関して参考にさせて頂いたのがこちら。
tips.hecomi.com

前準備 再生したいサウンドファイルを設定する

スクリプトを書いて、オブジェクトにコードをドラッグ&ドロップします。
そうするとInspectorに「Audio Source」の項目ができるので、▶︎をクリックして「AudioClip」に再生したいサウンドファイルをドラッグ&ドロップします。

スクリプト

状態を保持する時間を作っているので、音との同期が確実に正確ではありませんが、実験ではまあまあでした。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/* 
ボリュームに合わせてオブジェクトの大きさを変えたい場合に必要
using System.Linq;
*/

[RequireComponent(typeof(AudioSource))]	


public class SoundMoveScript : MonoBehaviour {

//256を1024にするともっと細かく検出できる
float[] wData = new float[256];

//「処理を止める処理」を停止するか否か
bool isRunning = false;



private AudioSource audioS;

	// Use this for initialization
	void Start () {
		
       audioS = GetComponent<AudioSource>();
	   
		
	}
	
	// Update is called once per frame
	void Update () {

/* 
ボリュームの変化に合わせてオブジェクトの大きさを変える場合はここだけ。他の変数との兼ね合いで変数名を変えてますが、例ほぼそのままです
		AudioListener.GetOutputData(wData, 1);
        var volume = wData.Select(x => x*x).Sum() / wData.Length;
        transform.localScale = Vector3.one * volume * 10;

		*/


		
		 float vol = GetMaxVolume();
		  Debug.Log(vol);
 
//ボリューム最大値が0.5以上のとき

   if(vol >= 0.5) {
	   gameObject.GetComponent<Renderer>().material.color = Color.blue;
	   transform.localScale = new Vector3(4, 4, 4);

   } 
  
    else {
		//0.5以上になったときの処理を停止する=状態を保持して、次の状態へ移行する
		StartCoroutine(TimeStop());


	}
 
 

	}


	float GetMaxVolume()
{ 

    float a = 0;
    audioS.GetOutputData(wData,0);
    foreach(float vMax in wData)
    {
    //最大値を取り出す
		a += Mathf.Max(vMax);
    }
	  
    return a/256.0f;
	
}


 



IEnumerator TimeStop() {  
	//「処理を止める処理」を開始する
	if( isRunning ) { yield break; }
	isRunning = true;


 	//2秒止める(状態を保持する)
  yield return new WaitForSeconds(2.0f);

//次の処理へ移行
	transform.localScale = new Vector3(1, 1, 1);
	gameObject.GetComponent<Renderer>().material.color = Color.red;

		//2秒止める(状態を保持する)
	yield return new WaitForSeconds(2.0f);
	//「処理を止める処理」を停止する(動き出す)
isRunning = false;



}


}