【Swift】SpriteKitの使い方。SKAudioNodeでサウンドを再生すると、リスナーとの相対距離や速度で音が変化する。(Swift 2.2、XCode 7.3)

2020年6月16日

SKAudioNodeとは

本記事ではSpriteKit Sceneファイルの編集画面(シーンエディタ)の部品一覧にあるSKAudioNode(以下、オーディオノード)について説明する。

SKAudioNode

 

オーディオノードとは、iOS9で新登場したサウンドを再生するノードである。サウンド再生の意味では過去に紹介した「AVAudioPlaer」や「PlaySoundFileNamedアクション」と一緒だが、オーディオノードは3D空間オーディオエフェクトという特徴的な仕様を持っている。

 

オーディオノードを使ってみる

実際にオーディオノードをシーンに配置してサウンドを再生してみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト

猿とスピーカーの2つのノードをシーンに配置し、ドラッグ&ドロップで運べるようにしておいた。この時点ではサウンドは再生されない。

 

下図赤枠のSKSファイルを選択してシーンエディタを開き、部品一覧からオーディオノードを配置したいところだが、オーディオノードを設定したあとに他のファイルを開くとXcodeがクラッシュして落ちる(Swift 2.2、XCode 7.3)。

プロジェクトの作り直しなど色々試してみたが必ず落ちてしまうので、今回はオーディオノードの配置にはSKSファイルは使わないことにする。なので下図はスルー。

SKAudioNodeをシーンに配置する

 

TestScene.swiftを以下のコードに変更する。オーディオノードを作成し、スピーカーノードの子として追加した(青色箇所)。

 

以下は実際のプレイ動画。スピーカーを画面左下に近づけると音が大きくなるのが分かっただろうか。

これは、シーン内にはlistener(以下、リスナー)と呼ばれるノードがいて、オーディオノードが発する音はリスナーが拾うためである。

リスナーを設定していない場合は、アンカーポイントがリスナーになる。そのため、画面左下のアンカーポイントにスピーカーを近づけると音が大きくなったということだ。

ちなみに、「リスナーの皆さん、こんばんは」のリスナーは視聴者という意味。

 

リスナーを猿ノードにしてみよう。

didMoveToViewメソッドにリスナーを設定するコードを追加する。

 

以下は実際のプレイ動画。スピーカーを運んで猿に近づけると音が大きくなる。逆に、猿を運んでスピーカーに近づけても音が大きくなる。

もし、両耳イヤホンがあれば耳に付けて聞いてみてほしい。猿に向かって右側にスピーカーを置くとイヤホンの右(R)の方が音が大きくなり、左側にスピーカーを置くとイヤホンの左(L)の方が音が大きくなる。

スピーカーを素早く動かして猿とクロスさせた場合は、「フォフゥー!」と風邪を切るような音になる。クロスが右⇒左ならに音も右⇒左、クロスが左⇒右なら音も左⇒右に流れるのが面白い。

 

自動再生、ループさせないようにする

デフォルトでは、オーディオノードを子に追加した時点でサウンドのループ再生が開始する。

サウンドが自動でループ再生されないようにするには、autoplayLoopedプロパティをfalseにする。その後、start、stopアクションを実行することでサウンドが再生される。

以下は、スピーカーをドラッグするとサウンドが開始し、ドロップするとサウンドが終了するコード

 

以下は実際のプレイ動画

 

3D空間オーディオエフェクトは無効にできないのか

公式リファレンスには、オーディオノードのpositionalプロパティをfalseにすれば、リスナーノードとの相対的な距離や速度の影響を受けない普通の音になるようなことが記載されているが、検証ではこのプロパティをtrue、falseのどちらにしても距離や速度の影響を受ける結果になった(Swift 2.2、XCode 7.3)。何か分かったら追記する。
⇒公式リファレンス「SKAudioNode

If YES, the audio mixer considers the position and velocity of the SKAudioNode relative to scene’s current listener node. The mixer applies distance attenuation, doppler shift, and pan effects to the sound. If NO, then the sound is played normally. The default value is YES.