This section explains the specifics of using Nice Vibrations on iOS or Android.


When using NiceVibrations, most of the time, you’ll just interact with the MMVibrationManager class. It’s been designed as an interface that calls platform specific methods based on context, so you don’t have to deal with platform detection all the time. That said, all the gamepad rumble, Android and iOS specific methods are exposed in their respective classes, and you can check out the API documentation to learn more about them. This page describes mostly initialization specifics.

Android specific methods


For Android to support vibrations you’ll need to have the following line in your Android manifest :

<uses-permission android:name="android.permission.VIBRATE" />


When targeting Android specifically with Nice Vibrations, there’s mostly only one method you have to deal with : AndroidVibrate(). It comes in different flavours, allowing you to do different things :

  • AndroidVibrate(long milliseconds) : will trigger a vibration of the specified duration (in milliseconds)
  • AndroidVibrate(long milliseconds, int amplitude) : will trigger a vibration of the specified duration (in milliseconds) and amplitude. The amplitude is a strength value that goes from 0 (light) to 255 (heavy)
  • AndroidVibrate(long[] pattern, int repeat) : will trigger a vibration based on the specified pattern.
  • AndroidVibrate(long[] pattern, int[] amplitudes, int repeat ) : will trigger a vibration based on the specified pattern and amplitude.

Here are some use examples :

MMVibrationManager.AndroidVibrate(100, 255);
MMVibrationManager.AndroidVibrate(new long[] { 0, 20, 40, 100 }, -1);
MMVibrationManager.AndroidVibrate(new long[] { 0, 20, 40, 100 }, new int[] { 0, 255, 0, 100 }, -1);

Patterns can get tricky to work with, so here’s how it goes : the first value in the array will indicate the initial delay before the vibration starts. Then, it’s a succession of durations for which you want the vibration to be on or off. So for example the following :

MMVibrationManager.AndroidVibrate(new long[] { 0, 20, 40, 100 }, -1);

would cause an Android device to vibrate instantly for 20ms, then wait for 40ms, and vibrate again for 100ms. And you could add amplitude to that too :

MMVibrationManager.AndroidVibrate(new long[] { 0, 20, 40, 100 }, new int[] { 0, 255, 0, 100 }, -1);

would cause an Android device to vibrate instantly and heavily for 20ms, then wait for 40ms, and vibrate more lightly again for 100ms. Oh and the -1 at the end is there to prevent repeat.

iOS specific methods

On “old” iOS, ideally you’ll want to initialize your haptics at the start of your scene, and release them when they’re not needed anymore. This is done through the iOSInitializeHaptics and iOSReleaseHaptics methods. You’re strongly encouraged to do so. If you don’t, they’ll be automatically initialized for you the first time you call for a vibration, but note that this may generate a slight delay or cause other issues down the line depending on your context.

Here’s how you initialize the haptic engine (ideally in Awake() in every scene) :

MMNViOS.iOSInitializeHaptics ();

And here’s how you release it when you don’t need vibrations anymore (ideally just before exiting your scene):

MMNViOS.iOSReleaseHaptics ();

On more recent iOS, this is done for you automatically.

Also note that Nice Vibrations uses a post processor (MMNVBuildPostProcessor) to ease the pain of setting up XCode to work with haptics, setting up permissions, paths, and frameworks for you. You can of course decide to not use the post processor (simply removing it from the project, or commenting it will do the trick) and modify these in XCode like you would for any project. If the paths don’t work for you, you can change them in the PostProcessor itself, the file described below, or in XCode directly.

Additionally, you’ll find a MMNVPathDefinition file in NiceVibrations/Common/Resources/ that you can edit to specify alternate paths :

  • PluginPath : the path to the plugin in XCode (usually Libraries/NiceVibrations/Common/Plugins/iOS/Swift/)
  • ModuleFileName : the name of the module (module.modulemap by default)
  • PluginRelativePath : the path in Unity (without Assets/, so usually NiceVibrations/Common/Plugins/Swift/)
  • ForceAlwaysEmbedSwiftStandardLibraries : whether or not the post processing build should force ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to true, it’s usually not needed, but it’s solved build errors for some people

Also good to know : iOS forbids haptics when the microphone is recording. Not the most common use case, but maybe will save someone a headache :)

Gamepad specific methods

You can of course trigger all sorts of gamepad rumble vibrations via the MMVibrationManager class, but if you want to target the gamepad specifically, you’ll want to do it via the MMNVRumble class. The only thing to know about it is that in most cases you’ll need to pass a monobehaviour to its methods, which will be used to run coroutines on. In most situations, you can just pass it this.

For example, this is how you make it rumble with full force for 2 seconds :

MMNVRumble.Rumble(1f, 1f, 2f, this);

In addition to that, Nice Vibrations lets you specify what gamepad to target when rumbling, using an optional additional parameter on all methods.

For example, this will rumble what Unity considers to be the “current” gamepad :

MMVibrationManager.Haptic(HapticTypes.Warning, false, true, this);

Which is good until you have more than one gamepad, in which case it becomes less predictable. But you can add an extra parameter to specify the index of the gamepad you want to target (0 is the first gamepad, 1 is the second, 2 is the third, etc) :

// triggers a rumble on the 3rd gamepad
MMVibrationManager.Haptic(HapticTypes.Warning, false, true, this, 2);

Note that for gamepad access you’ll need to install Unity’s new Input System package via the Package Manager.