#目標
Unityのゲームで一定の場合には(例えば、GameObjectの衝突が発生した場合)iPhoneを短くかつ弱く振動させることです。
Unityの「Handheld.Vibrate()」を簡単に使ったらバイブレーション自体はできますが、振動の強さ・長さ・種類は一切調整できないため(実機でテストしてみたら、結構強い振動でした。)、必ずほかの方法を見つけないといけません。
#解決方法
iOSは、AudioToolbox.frameworkのAudioServicesでさまざまな効果音とバイブレーションを用意してくれています。
しかし、Unityから直接にiOSのAudioServicesを呼び出すことがまだ不可能らしいので、「iOS用のプラグインをビルド」という方法で間接的に呼び出せるようにします。
手順は以下の通りです。(もう自分のUnityゲームで実装済み)
###①Object-CのスクリプトplaySystemSound.mmを作成します。
#import <Foundation/Foundation.h>
#import <AudioToolBox/AudioToolBox.h>
extern "C" void playSystemSound (int n)
{
AudioServicesPlaySystemSound(n);
}
名前はplaySystemSoundじゃなくても何でも可。言語はObject-CじゃなくてC++(.cpp)でも問題無さそうだけど、未検証のため、ご興味のある方は自分で試してみてください。
###②作成したplaySystemSound.mmファイルをUnityのAssetsフォルダの下に置きます。
Assetsフォルダーの下ならどこでも可。
###③UnityのC#スクリプトにplaySystemSoundメソッドを呼び出すコードを作成します。
自分のゲームのプログラムを例として説明します。
GameObject「Target」の衝突があった時にiPhoneを振動させるとします。
まず、「Target」には「TargetController.cs」というC#スクリプトをアタッチします。
Targetの衝突があった時、Unityが自動的にOnTriggerEnter関数を呼び出すので、「振動させる」コードをOnTriggerEnterの中に書くとよいでしょう。
public class TargetController : MonoBehaviour
{
/* ほかのコード略 */
[DllImport("__Internal")]
private static extern void playSystemSound(int n);
/* ほかのコード略 */
private void OnTriggerEnter(Collider other)
{
/* ほかのコード略 */
#if UNITY_EDITOR
Debug.Log("Play system sound or vibration on real devices");
#else
playSystemSound(1519);
#endif
/* ほかのコード略 */
}
ここで 注意 していただきたいのは、もし、Unity EditorでplaySystemSoundを呼び出すと、下記のような「EntryPointNotFoundException」が出てしまうのです。 iPhone実機で実行するとそういうExceptionは出ない ので、「#if UNITY_EDITOR」(プラットフォーム依存コンパイル)を使ってUnity Editorの場合を外したほうが無難です。
なお、playSystemSound(int n)のパラメータ「n」は、 「1519」 を使うと 「プッ」という短い・弱いバーブレーション になります。
別途で「1005」を試してみました。iPhoneをミュートするとシステムアラームの振動と同じようなバイブレーションが出ました。逆にiPhoneをunmuteするとvibrationが出なくてアラームの効果音だけが出ました。
ほかのパラメータについて、ご興味のある方自分で試してみてください iOS Predefined sounds
以上です。