【Unity】アプリのバイブレーション制御
バイブレーション制御
ボタンを押したことを知らせるバイブレーションを作りたい。
バイブレーションは端末側の機能なのでIOS,Android,といったOSによって別々に書かなくてはならない。
(一応unityでもサポートされてるといえばされてるけど、1秒固定で使い勝手が悪いのだ。)
環境
windows10
unity 2017 1.0.p5 personal
Android
ネイティブコードは規定のフォルダ内に収めなくてはエラーが起こる。
まずはネイティブを入れるフォルダ管理から。
フォルダ管理
(なければ)project 内にPluginsフォルダを作る。pluginsフォルダ内にAndroidフォルダを作る。
こんな感じに。詳しいことはネットに色々落ちてるから省略。
コーディング
AndroidのネイティブはUnityとの連携が上手くいかなかったので、javaは諦めてC#プラグインで書くことにする。
さっきのAndroidフォルダ内に
VibrateAndroid.csとしてこんな感じに
using UnityEngine; using System.Collections; public static class Vibration { #if UNITY_ANDROID && !UNITY_EDITOR public static AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); public static AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); public static AndroidJavaObject vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator"); #else public static AndroidJavaClass unityPlayer; public static AndroidJavaObject currentActivity; public static AndroidJavaObject vibrator; #endif public static void Vibrate() { if (isAndroid()) vibrator.Call("vibrate"); else Handheld.Vibrate(); } private static bool isAndroid() { #if UNITY_ANDROID && !UNITY_EDITOR return true; #else return false; #endif
これでVibrate.Vibrate()呼び出せばAndroidがブルブルする。
振動秒数を調節したければ
public static void Vibrate(long milliseconds) { if (isAndroid()) vibrator.Call("vibrate", milliseconds); else Handheld.Vibrate(); }
こんな関数をclass内に追加すれば
Vibration.Vibrate(500);
なんかで500マイクロ秒振動できる。
iOS
iOSはAndroidほどの自由度はない。できることは連続振動と0.5秒ほどの振動だけ。
やり方はAndroidと同様に、フォルダをPlugins内に作る。
iOS内に作るファイルは2つ。
1.c#ファイル
2.橋渡しのmmファイル
まずはc#から。
using System.Runtime.InteropServices; namespace Iphone.vib { /// <summary> /// iOSバイブレーションネイティブプラグイン /// </summary> public static class VibrationPlugin { #if !UNITY_EDITOR && UNITY_IOS [DllImport("__Internal")] static extern void _PlayVibration (int i); #endif public static void PlayVibration(int frequency) { #if !UNITY_EDITOR && UNITY_IOS _PlayVibration(frequency); #endif } } }
だいたいこんな感じ。
ファイル名にVibrationPlugin.csとでもつけて保存。
ファイル名に一貫性がない。(´・ω・`)
絶対あとでわけわからんくなる。(´・ω・`)
次に.mmファイル。
.mmはc++とobjectiv-cの合体させたiOSアプリファイルだよーって聞くけど、詳しいことは謎。
VibrationPluginBridge.mmとでもつけて作成
#import <Foundation/Foundation.h> #import <AudioToolbox/AudioServices.h> extern "C" { int cnt = 1; void ExecuteVibration(SystemSoundID ssID,void *clientData) { if (cnt > 0) { [NSThread sleepForTimeInterval:(NSTimeInterval)1.0]; AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } else{ AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate); } cnt--; } void _PlayVibration(int i) { cnt = i; AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate,NULL,NULL,ExecuteVibration,NULL); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } }
これでVibrationPlugin.PlayVibration(0);で1度振動。 数を増やすと連続振動する。
これより短い振動を使いたい場合は、ゴリ押しだけど内部で定義されたものを無理やり使う。
ざっと調べたところ、ショートメールが来たときの振動が一番短いと思う。
mmファイルの
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
と
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate,NULL,NULL,ExecuteVibration,NULL);
を全て削除なりコメントアウトなりして、
AudioServicesPlaySystemSound(1003); AudioServicesDisposeSystemSoundID(1003);
を書き加える。
するとIOSで最少時間のバイブレーションが鳴らせる。
もっと良いやり方があればぜひご教授を!!(`・ω・´)