マイクが拾った音量分オブジェクトを拡大するコードをnoteの記事を参考に書いてみました
実際に書いたコード↓
using System;
using System.Linq;
using UnityEngine;
public class AudioClipController : MonoBehaviour
{
[SerializeField] private string m_DeviceName;
private AudioClip m_AudioClip;
private int m_LastAudioPos;
private float m_AudioLevel;
private GameObject[] m_VoiceObjects; // タグ「Voice」を持つオブジェクトの配列
private Vector3[] m_OriginalScales; // オリジナルのスケールを保持する配列
private Vector3[] m_NowScales; // 現在のスケールを保持する配列
private Vector3[] m_TargetScales; // 目標のスケールを保持する配列
[SerializeField, Range(10, 100)] private float m_AmpGain;
[SerializeField] private float m_ScaleChangeSpeed; // スケールの変更速度
void Start()
{
string targetDevice = "";
foreach (var device in Microphone.devices)
{
Debug.Log($"Device Name: {device}");
if (device.Contains(m_DeviceName))
{
targetDevice = device;
}
}
Debug.Log($"=== Device Set: {targetDevice} ===");
m_AudioClip = Microphone.Start(targetDevice, true, 10, 48000);
// タグ「Voice」を持つすべてのオブジェクトを取得
m_VoiceObjects = GameObject.FindGameObjectsWithTag("Voice");
// 配列のサイズを設定
m_OriginalScales = new Vector3[m_VoiceObjects.Length];
m_NowScales = new Vector3[m_VoiceObjects.Length];
m_TargetScales = new Vector3[m_VoiceObjects.Length];
// 各オブジェクトのオリジナルのスケールを保持
for (int i = 0; i < m_VoiceObjects.Length; i++)
{
m_OriginalScales[i] = m_VoiceObjects[i].transform.localScale;
}
}
void Update()
{
float[] waveData = GetUpdatedAudio();
if (waveData.Length == 0) return;
m_AudioLevel = waveData.Average(Mathf.Abs);
// オブジェクトごとにスケールを計算
for (int i = 0; i < m_VoiceObjects.Length; i++)
{
float newScaleX = m_OriginalScales[i].x + m_AmpGain * m_AudioLevel;
m_TargetScales[i] = new Vector3(newScaleX, m_OriginalScales[i].y, m_OriginalScales[i].z);
// スケールの変更速度を調整
float scaleChangeSpeedAdjusted = m_ScaleChangeSpeed;
if (newScaleX < m_NowScales[i].x) // 新しいサイズが元のサイズより小さい場合
{
scaleChangeSpeedAdjusted *= 0.04f; // 変更速度を半分にする
}
// スケールを補完して変更
m_VoiceObjects[i].transform.localScale = Vector3.Lerp(m_NowScales[i], m_TargetScales[i], Time.deltaTime * scaleChangeSpeedAdjusted);
m_NowScales[i] = m_VoiceObjects[i].transform.localScale;
}
}
private float[] GetUpdatedAudio()
{
int nowAudioPos = Microphone.GetPosition(null);// nullでデフォルトデバイス
float[] waveData = Array.Empty<float>();
if (m_LastAudioPos < nowAudioPos)
{
int audioCount = nowAudioPos - m_LastAudioPos;
waveData = new float[audioCount];
m_AudioClip.GetData(waveData, m_LastAudioPos);
}
else if (m_LastAudioPos > nowAudioPos)
{
int audioBuffer = m_AudioClip.samples * m_AudioClip.channels;
int audioCount = audioBuffer - m_LastAudioPos;
float[] wave1 = new float[audioCount];
m_AudioClip.GetData(wave1, m_LastAudioPos);
float[] wave2 = new float[nowAudioPos];
if (nowAudioPos != 0)
{
m_AudioClip.GetData(wave2, 0);
}
waveData = new float[audioCount + nowAudioPos];
wave1.CopyTo(waveData, 0);
wave2.CopyTo(waveData, audioCount);
}
m_LastAudioPos = nowAudioPos;
return waveData;
}
}
これを適当な空のオブジェクトにアタッチすると
タグ「Voice」をもつすべてのオブジェクトがX方向に拡大され、徐々に縮小されます
m_AmpGainとm_ScaleChangeSpeedは自分がやった時は両方とも100で統一しましたが
お好みで変えてください
スケールが操作できるならば
座標や回転などもマイク入力で操作できそうね
参考にさせていただいた記事↓