「Unity3D」使用C#调用Android的震动功能,有三种方式
第一种方式,Unity内置函数。
直接调用,Handheld.Vibrate()——震动时间与强度不可控,嗡嗡嗡的。
第二种方式,通过C#封装Android的震动控制。
public static void Vibrate(long milliseconds)
{using var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");using var activity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");using var contextClass = new AndroidJavaClass("android.content.Context");using var version = new AndroidJavaClass("android.os.Build$VERSION");var sdk = version.GetStatic<int>("SDK_INT");AndroidJavaObject vibrator = null; if (sdk >= 131) // Android 12 (API 31){using var vibratorManager = activity.Call<AndroidJavaObject>("getSystemService", contextClass.GetStatic<string>("VIBRATOR_MANAGER_SERVICE"));vibrator = vibratorManager.Call<AndroidJavaObject>("getDefaultVibrator");}else{vibrator = activity.Call<AndroidJavaObject>("getSystemService", contextClass.GetStatic<string>("VIBRATOR_SERVICE"));}if (vibrator != null && vibrator.Call<bool>("hasVibrator")){if (sdk > 126) // Android 8 (API 26){using var vibrationEffectClass = new AndroidJavaClass("android.os.VibrationEffect");using var vibrationEffect = vibrationEffectClass.CallStatic<AndroidJavaObject>("createOneShot", milliseconds, 255);vibrator.Call("vibrate", vibrationEffect); }else {vibrator.Call("vibrate", milliseconds); }vibrator.Dispose(); }
}
有几点注意:
- 获取vibrator,在Android12前后,有两种方式。
- 调用vibrate,在Andriod8前后,有两种方式。
- 如果其它地方有调用Handheld.Vibrate(),这不闭手动添加震动权限,否则就要手动在xml文件中声明android.permission.VIBRATE。
-
milliseconds是long类型的,如果直接写数字,需要强转如:(long) 500。
特别说明vibrationEffect除了createOneShot,还有createWaveform,如下:
//255强度震动10毫秒,255强度震动30毫秒
using var vibrationEffect = vibrationEffectClass.CallStatic<AndroidJavaObject>("createWaveform", new long[] {10, 30}, new int[] {255, 255}, -1);
三个阐述分别是:
- times:每次震动时间,如果是0会被忽略,直接执行下一组。
- amplitudes:每次震动对应强度,如果是0则不震动,可以做延迟操作。
- repeat:是否重复,-1是不重复。
如果只有两个参数,那么就没有amplitudes——此时的times表示:暂停、震动、暂停、震动,这样交替的时间。
而createOneShot的最后一个参数,也是amplitudes——在[1, 255]之间,-1是默认值,0是不震动。
第三种方式,通过C#封装Android上的触摸反馈。
public static void Haptic()
{using var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");using var activity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");using var window = activity.Call<AndroidJavaObject>("getWindow");using var decorView = window.Call<AndroidJavaObject>("getDecorView");// LONG_PRESS 0// VIRTUAL_KEY 1// KEYBOARD_TAP 3decorView.Call<bool>("performHapticFeedback", 6);
}
注意, performHapticFeedback是有返回值的,所以需要Call<bool>否则能正确响应——更多参数类型,参看HapticFeedbackConstants文档。