Unityを使ってWebGL向けのゲームを作っている真っ最中のふーすけです。
今作っているゲームは「マイク入力」を使って操作しようとしているのですが、WebGLでビルドしようとしたら問題に遭遇しまして…
なんと「Microphone」クラスはWebGL未対応でした!!!!!←
まぁちゃんと調べとけって話なんですが、調べたところ有料アセットだったり、Githubプロジェクトでプラグインを提供されてたりと、皆さん何かしらの回避方法で対応してらっしゃるらしいです。
どうしようかなーと思ったんですが、今回やりたいことは「マイク入力で周波数を取りたい」だけだし、ネイティブプラグイン作れるんじゃね?(JS未経験だけど!)と思ったのでチャレンジしてみました。
ということでChatGPTくんを駆使して、以下のネイティブプラグインを作ってみました。
// Unity WebGLビルドにマイク入力処理を追加
mergeInto(LibraryManager.library, {
StartMicrophoneCapture: function () {
console.log("* start StartMicrophoneCapture");
// getUserMedia がサポートされているかチェック
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.error("***** getUserMedia is not supported");
return;
}
// マイクの音声入力を取得
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function (stream) {
// AudioContext の作成(ブラウザ互換対応)
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
// マイクストリームからオーディオノードを作成
const micSource = audioContext.createMediaStreamSource(stream);
// 音声処理ノードの作成(バッファサイズ: 1024サンプル, mono)
const processor = audioContext.createScriptProcessor(1024, 1, 1);
// 音声データが入力されるたびに呼ばれる処理
processor.onaudioprocess = function (event) {
// 左チャンネル(0)のデータを取得(Float32Array)
const input = event.inputBuffer.getChannelData(0);
// Unity側に渡せるように通常の配列へ変換
const floatArray = Array.from(input);
// Unity側の PitchDetector.OnMicPCMJson に送信
if (typeof unityInstanceGlobal !== 'undefined') {
console.log("***** sendMessage: OnMicPCMJson");
unityInstanceGlobal.SendMessage("PitchDetector", "OnMicPCMJson", JSON.stringify(floatArray));
} else {
console.warn("***** unityInstanceGlobal is undefined!");
}
};
// マイク入力 → 処理ノード → 出力先(スピーカー等)へ接続
micSource.connect(processor);
processor.connect(audioContext.destination);
})
.catch(function (err) {
console.error("***** マイク取得失敗:", err);
});
}
});
とりあえず上記プラグインをUnity側で実行して呼び出したところ、ちゃんとブラウザで音声取得できました。
とはいえJavaScriptわからないマンなのでまだ自分でもお試し中です。
あまり内容は信用しないでくださいw(アドバイスはお待ちしております!)
おそらく上記コードをベースにこれから修正していきますが、
大きな変更点や考慮漏れ、不具合などがあれば、また記事にしたいと思います。
コメント