-
Notifications
You must be signed in to change notification settings - Fork 18
1. Nice Vibrations developer documentation
Nice Vibrations is a simple yet powerful solution for adding high-definition (HD) haptic feedback to your iOS, Android, PC and console games with Unity. Developed in partnership with More Mountains, and implemented on top of the Lofelt SDK, Nice Vibrations offers a universal interface to easily target iOS and Android devices, and gamepads, all at once.
This offers multiple options for playing haptics. You can use:
- 120+ free haptic clips designed by Lofelt
- Custom haptic clips that you design using the .haptic file format.
- Haptic presets, which offer a subtle way to trigger predefined haptics patterns on all platforms
- Constant haptics, which provide continuous haptics, generated in real time, with varying amplitude and frequency over time
- Emphasis haptics, which are short haptic bursts whose amplitude and frequency can be controlled in real time
You can download the Nice Vibrations asset in the GitHub Releases of this repository.
- Nice Vibrations is the #1 proven and battle-tested haptics asset for Unity.
- It is used by tons of game developers and studios around the world ー from teams working on hypercasual games on mobile to AAA titles on PCs and consoles
Nice Vibrations 4 is loaded with exciting new features and APIs that streamline workflows and can significantly improve game feel, such as:
⏯ Playback of a universal haptic format: Play and stop haptic clips (.haptic files).
🔋 Improved performance: On iOS, playing and loading haptic clips is 2 times faster than Nice Vibrations 3.9.
🔁 Loop: Loop a playing clip.
👟 Seek: Jump to any point of your haptic clip before or during playback in response to game events.
💥 Modulate frequency or amplitude: Adjust the strength or frequency of your playing haptic clip. You can have the clip respond to on-screen events (such as the distance between characters or size of a collision) or create variations in the pattern playback (for repetitive actions such as weapons firing, footsteps or jumps).
🚦 Haptic voice priority: Set the priority of your haptic clip. Lower-priority clips will be silenced if higher-priority clips are triggered at the same time.
📜 Code-only API: Work in any development workflow using the code-only API. You are not limited to Unity and MonoBehaviour.
💻 MonoBehaviour API: Play haptics by using only the Unity Editor, without writing a single line of C# code.
🪐 Platform independence: Use the same C# and the same .haptic file on all platforms. There is no need to write platform-specific code for Android or iOS.
📚 Haptic library: Get started quickly ー even with limited experience ー by tapping into the included library of 80+ clips.
🎮 Gamepad rumble: Support for Mac & Windows gamepad controllers for which Unity Input Systems supports rumble.
🧱 Haptic Presets: Trigger 9 predefined haptic patterns with a single line of code.
📳 Fallback support: Automatically trigger a Haptic Preset of choice on older phones and operating systems.
AHAP playback support is not available in Nice Vibrations 4. Nice Vibrations supports playback using .haptic files.
If you still want to use Nice Vibrations 3.9, you can use the package inside the folder "OlderVersions/3.9". Make sure to remove the Nice Vibrations 4 folder completely from your project if you want to use Nice Vibrations 3.9.
To learn how to port from Nice Vibrations 3.9, check out this section.
Nice Vibrations will let you get the best of each platform's haptics API, in a unified way. Of course, you'll get better-quality haptics on hardware that is designed to deliver better haptics. In general, iOS phones perform much better than Android phones and provide more control, so users will have a much satisfying experience on iPhones. Gamepads, meanwhile, vary greatly in the degree to which they let you fine-tune vibrations.
Mobile devices: iPhones and Android phones are supported.
Consoles: Nice Vibrations completely supports PS4, Xbox and Switch controllers when connected to their respective consoles. You may have to install additional console-specific input packages from Unity in your project. For more, check the Gamepad requirements.
PCs: PS4 and Xbox controllers are supported.
Macs: Only PS4 controllers are supported for now.
The plug-in works in Unity with version 2019.4.16 LTS and the latest stable releases.
If you're targeting Android devices, PCs or consoles, you can build anywhere. If you want to build for iOS, you need to build on a Mac. Building on Windows will work in most situations, but doing so may be more complex depending on your context. Building on Unity Cloud Build, at the moment, will very likely not work, due to Unity changing how they handle bridging to native APIs.
This documentation covers all there is to know about Nice Vibrations and will let you get started quickly. If you really want more, you can:
- Clone the repo and build the API documentation generated by Doxygen. You can use the
generate-api-docs.sh
available ininterfaces/unity
folder and then opendoxygen/html/index.html
on your browser. - Or, open up the asset's scripts and look under the hood. All methods and fields are fully commented on to let you know how it all works.
If you're running Unity 2019.4.16f or newer, you'll see these folders after importing the asset.
If you don't see this structure, you are probably running an older version of Nice Vibrations. In that case, you should update Unity to a more recent version (v2.0 is available for Unity 2019.2.9, v3.0 is available starting with Unity 2019.3 and v4.0 is available starting with Unity 2019.4.16f).
We recommend that you do not remove anything from the contents of the asset. But if for some reason you need to, here's what is in each folder:
- Scripts: All the scripts required to trigger haptic playback. We strongly recommend that you do not remove anything from this folder.
- HapticSamples: 80+ royalty-free haptic clips designed by Lofelt. The clips cover a wide range of use cases so you can get started in seconds.
- Demo: The demo scenes that showcase the potential of the asset. In the Demo folder's "Common" folder you'll find scripts used in most demos to handle the UI and other common features. You can delete the whole Demo folder if you feel like you don't need itーit's completely optional.
- Plug-ins: Lofelt SDK libraries for iOS and Android, providing the core functionality to Nice Vibrations.
- OlderVersions: Previous versions of Nice Vibrations, just in case switching to the very latest doesn't work for your project. This folder contains .unitypackages, which you can simply unpack into your project. If you decide to do so, remove the latest version first. Currently, you still need to do this if you want AHAP support.
Choose from 80+ royalty-free haptic samples, covering use cases such as application UX, sound FXs, music and more. These samples will help you make your games more immersive faster.
Nice Vibrations 4 comes with seven demos, showcasing the various haptic feedback options that the plug-in offers. You also get the complete code for these demos, so you can see the asset's methods in action:
-
Wobble: Tiny wobble pads trigger a GameObject component HapticSource when touched. Each plays a differently pitched sound and haptics.
-
Ball: A bouncing ball triggers emphasis haptics of varying amplitude and frequency based on fall height.
-
Continuous: This demo lets you trigger continuous haptics at a selected amplitude, frequency and duration. You can change the amplitude and frequency of the continuous haptic effect as it plays.
-
HapticClips: This example lets you explore nine different pre-designed haptic clips. These were designed to match their associated sounds.
-
Emphasis: You can experiment with an emphasis haptic, which provides short, controlled haptic feedback.
-
Car: Turn the knob left and right, and feel the car's engine accelerate. Be careful not to run out of gas!
-
Base presets: Use the base preset demo to experience the nine different basic haptic patterns (currently using Nice Vibrations 3.9 only).
To update the Nice Vibrations engine, remove the old NiceVibrations folder and import the new one. If you don't remove the old folder, some scripts might be duplicated and not removed.. Depending on what version you're updating from, and what version you're updating to, you may have some light refactoring to do. For more about how to port your code to Nice Vibrations 4, check this section.
To start using Nice Vibrations, simply import the asset package and place the NiceVibrations folder in your project. That's it.
If you want to work with the code-only API, you don't need to add anything to your scene(s) or add any components. You can call Nice Vibrations' methods from anywhere in your scripts.
Note that you need to add the Nice Vibrations namespace at the top of your scripts that call vibrations, but most IDEs will add that for you:
using Lofelt.NiceVibrations;
If you prefer to use MonoBehaviours, you can add components to your GameObjects in your scene to trigger haptics without having to write any code, similar to how you would incorporate audio. Check the Haptic Components section below for more details.
See the API documentation for more details about the code-only and the MonoBehaviour APIs.
Not all devices support haptic feedback, and not all devices support haptics equally.
The requirements for playing haptics with Nice Vibrations depend on the following criteria:
- The device should have an actuator.
- The device platform should support the required native haptic APIs.
You can check the minimum requirements necessary for your device to play haptics.
These are the device's minimum requirements to play haptics with Nice Vibrations:
Device | Minimum requirements |
---|---|
iPhone | iPhone 7 or newer iOS 11 or newer |
Android phone | Android API level 17 (Jelly Bean) Have an actuator |
Gamepad | Gamepads that support Rumble with the new Unity Input System Check this section for more information |
Depending on the device and platform, Nice Vibrations supports multiple types of haptic capabilities.
With basic capabilities, it is possible to trigger predefined haptics. Some platforms, like Android, might even allow to control the duration of some vibrations, but not their intensity. If the device only has this capability, it cannot play haptic clips.
To check if your device has basic haptic capabilities, check this property:
bool hapticsSupported = DeviceCapabilities.isVersionSupported;
If this value is false
it means that your device does not support haptic
playback with Nice Vibrations.
Advanced capabilities allow to control the vibrations intensity and play haptic clips.
To check if the device has advanced haptic capabilities, we need to know if it meets the necessary requirements with:
if (DeviceCapabilities.meetsAdvancedRequirements == true)
For information about what devices have advanced haptic capabilities, check the Device requirements page.
This capability depends on having advanced capabilities. It allows control of amplitude or frequency at run time, without the need to stop haptic playback.
To check if your device allows real time control of amplitude or frequency - modulation - you can check:
bool amplitudeModulationSupported = DeviceCapabilities.hasAmplitudeModulation;
bool frequencyModulationSupported = DeviceCapabilities.hasFrequencyModulation;
Ideally, we would like all device to have advanced and real-time control capabilities. But unfortunately, that is not the case specially with gamepads and Android.
Nice Vibrations won't do anything for functionality not supported on a specific platform, or you may wish to enable fallback support for older devices. No need to add any guard checks to your code.
One example is HapticController.clipFrequencyShift
. At the moment of this
writing, it won't have any impact for Android devices but you don't need to have
a guard check to know if the device supports it. No errors, warnings or
exceptions will be raised. It simply won't do anything on Android.
Another example is when DeviceCapabilities.meetsAdvancedRequirements
is
false
. This means that it is not possible for the device to play haptic clips.
But, it is possible to fallback to a haptic
preset as we will see in one of the next sections.
However, you could decide at runtime what to do in case some capabilities are
not present. You can check with the class DeviceCapabilities
. More details can
be found in the API documentation.
Nice Vibrations offers many methods for triggering all sorts of vibrations. You can start by triggering emphasis haptics. An emphasis haptic is a short but intense vibration ー it can be played on both iOS and Android devices. You can call it from anywhere like this:
HapticPatterns.PlayEmphasis(1.0f, 0.0f);
The parameters are the amplitude and frequency of the vibration. The amplitude refers to the strength of the vibration. The frequency refers to the pitch or tone of the haptic effect. The frequency becomes higher as the value increases. You can play around with those values to get a better sense of the experience.
For another simple way to trigger a constant vibration for a specified amount of time, use:
HapticPatterns.PlayConstant(1.0f, 0.0f, 1.0f);
This plays a constant vibration with amplitude 1.0 and frequency 0.0 for 1 second. You can also play it for longer, of course.
As you probably noticed, the static class for both of the methods above is called HapticPatterns. This class allows you to play predefined simple vibration patterns that are baked into the plug-in and let you easily start adding haptics to your game.
With the HapticPatterns class you can play haptic presets in case you just need simple and short haptic patterns without the fine grained details of a haptic clip.
This class has 9 predefined haptic patterns that allow you to easily add subtle haptics to your scenes.
You can also trigger them on Unity supported versions of Android devices that have a vibration motor, and on iOS devices from iPhone 7 / iOS 11 and newer.
For example, you can trigger a "Warning" haptic preset with this single line of code:
HapticPatterns.PlayPreset(HapticPatterns.PresetType.Warning)
In addition to playing HapticPatterns, you can also play a HapticClip. A haptic clip contains HD, device-agnostic haptic data that Nice Vibrations uses to create an optimal haptic effect on playback devices.
Any haptic clip that you wish to use in your Unity application must first be added to the project. Specifically, the haptic clips (files ending with the extension .haptic) must be added to the Assets folder (or a sub-folder of your choosing) in the project. You can either directly drag haptic clips to this folder in Finder/Explorer, or you can drag them into the Unity Project Explorer.
You can immediately use the haptic clips available in the HapticSamples folder.
Here's an example of how to play a haptic clip:
using UnityEngine;
using Lofelt.NiceVibrations;
public class PlayerCharacter : MonoBehaviour
{
// Shows a GUI element in the inspector window to select a jump haptic
public HapticClip jumpHaptic;
public void Jump()
{
// Plays the jumpHaptic
HapticController.Play(jumpHaptic);
}
}
If you are using code similar to the script above, you will need to go next to the Unity Editor, choose the HapticClip from the HapticSamples folder, and drag and drop it into the Inspector property of your script, in this case, "Jump Haptic."
Once HapticPatterns.PlayConstant(..)
or HapticController.Play(..)
is called,
you might want to stop haptics before they finish. To do that, you simply need
to call:
HapticController.Stop()
And that's it.
In cases where the device doesn't have the ability to play haptic clips -
meaning that DeviceCapabilities.meetsAdvancedRequirement
returns false
-
you can instead trigger a fallback haptic preset, like in the example below:
HapticController.fallbackPreset = HapticPatterns.PresetType.Selection;
HapticController.Play(jumpClip);
This example will play the haptic clip jumpClip
or the fallback haptic preset
HapticPatterns.PresetType.Selection
. This is done automatically by
HapticController.Play(HapticClip clip)
, which checks for
DeviceCapabilities.meetsAdvancedRequirement
and decides to play a haptic clip
or haptic preset.
There is much more you can do with Nice Vibrations beyond adding haptics to your game. For example, you can jump to a specific time in a haptic clip, control the amplitude and frequency of haptics whenever you like, add haptic components to GameObjects and more.
With Nice Vibrations, you can jump ahead or back to a specific time within a haptic clip:
HapticController.Load(jumpHaptic);
HapticController.Seek(0.2);
HapticController.Play();
Seek(float time)
requires a haptic clip to be loaded before being called, and
it is only applied after play. In this case, it will jump to 0.2 seconds in the
haptic clip.
We could also loop a clip to achieve different kinds of haptic effects with just one haptic clip.
HapticController.Load(loopHaptic);
HapticController.Loop(true);
HapticController.Play();
This will make the haptic clip loopHaptic
play in a loop until
HapticController.Stop()
is called.
For more details, check the API documentation
Nice Vibrations allows you to control haptics at runtime. Specifically, you can modulate a haptic clip by changing its amplitude and frequency breakpoints with:
// Multiplies all amplitude envelope breakpoints by 0.7
HapticController.clipLevel = 0.7;
// Shifts all the frequency envelope breakpoints by 0.2
HapticController.clipFrequencyShift = 0.2;
clipLevel
is equivalent to a "volume control" in audio. In this case you can
attenuate for values below 1.0 and add gain with values above 1.0. Values above
1.0 will be clipped to 1.0
clipFrequencyShift
allows you to set the "pitch" or "tone" of the haptic clip
by adding a desired value between -1.0 and 1.0, clipped to 1.0.
To see how you might use these capabilities, check out the Car demo tab from the
Demo/NiceVibrationsDemo.unity scene. The method HandlePower()
from
CarDemoManager.cs script shows how turning the knob to increase/decrease the car
speed can produce haptics that change in real time based on user interactions.
First, HapticPatterns.PlayConstant(..)
is called with values provided by the
Knob class. This sets the initial values for triggering a constant vibration.
protected virtual void HandlePower()
{
_knobValue = Knob.Active ? Knob.Value : 0f;
if (!_carStarted)
{
...
HapticPatterns.PlayConstant(_knobValue, _knobValue, MaximumPowerDuration);
CarEngineAudioSource.Play();
...
}
...
}
As the user interacts with the knob, the amplitude and frequency of the constant
vibration need to be updated to match the user's interaction.
HapticController.SetAmplitudeMultiplication(float factor)
and
HapticController.ShiftFrequency(float shift)
are used to create real-time
modulation of amplitude and frequency.
For that, HapticController.clipLevel
and HapticController.clipShiftFrequency
are used to create real-time modulation of amplitude and frequency.
clipLevel
increases or decreases the amplitude of haptics and
clipFrequencyShift
shifts the pitch of the vibration. With this combination,
you can get a similar effect when you press the gas pedal of a car: As you press
the pedal, you can feel the motor noise and vibrations increase in both
strengths and in pitch.
if (_knobValue > MinimumKnobValue)
{
Power -= Time.deltaTime;
Power = Mathf.Clamp(Power, 0f, MaximumPowerDuration);
HapticController.clipLevel = _knobValue;
HapticController.clipFrequencyShift = _knobValue;
...
}
Alternatively, you could use a HapticClip instead of HapticPatterns. In that case, you would not use:
HapticPatterns.PlayConstant(_knobValue, _knobValue,
MaximumPowerDuration);
CarEngineAudioSource.Play();
Instead, you would initialize playback with:
HapticController.Play(carEngineHaptic); //carEngineHaptic is defined as HapticClip carEngineHaptic
HapticController.clipLevel = _knobValue;
HapticController.clipFrequencyShift = _knobValue;
CarEngineAudioSource.Play();
The code for the real-time modulation of amplitude and frequency based on knob interactions stays the same.
With Nice Vibrations, you can get callbacks when haptic effects are done playing. To generate those callbacks, just write the following code in one of your classes:
protected void OnHapticsStopped()
{
// do something when haptics stop - usually because they have finished playing
}
protected virtual void OnEnable()
{
HapticController.PlaybackStopped += OnHapticsStopped;
}
protected virtual void OnDisable()
{
HapticController.PlaybackStopped -= OnHapticsStopped;
}
You can see this in action in the continuous demo tab.
Nice Vibrations offers global controls, such as global output level and haptics enabled. Haptic effects are amazing, but sometimes you just want to turn them off or lower the level. To turn haptics off and on, you can call:
// turns all haptics off
HapticController.hapticsEnabled = false;
// turns all haptics on
HapticController.hapticsEnabled = true;
And to adjust the global output level, similar to "main volume" for haptics, you can call:
// adjusts vibration strength to 0.5
HapticController.outputLevel = 0.5;
So far, we have been covering the code-only API of Nice Vibrations 4. You can also add components to your scene to play haptic clips without writing code or by writing very little code in your scripts.
In Unity, the audio system works by assigning audio assets to various GameObjects. The final audio mix is then determined by the positions of these GameObject around the player or camera. The camera is equipped with an Audio Listener component; the player has an Audio Source component.
Nice Vibrations components work on a similar principle. HapticSources can be assigned to various GameObjects, and you can trigger playback on the occurrence of an event or through your scripts.
The first component you need to add to a GameObject is HapticReceiver. You should only add it to one GameObject that lives throughout the whole application. In most cases, you should add this to your MainCamera GameObject, similar to how you would to with AudioListener. Make sure there is one, and only one*, *HapticReceiver component in your project.
See how this works in our demo scene, above on the bottom right, where a HapticReceiver is used in the MainCamera.
Through HapticReceiver, you can also set the global output level and turn haptics on or off.
Below is an example of how to use the HapticReceiver properties without writing any code, something like a HapticSwitch from the demo scene.
The HapticSource component is similar to AudioSource. HapticSource is responsible for playing a HapticClip.
You can set all kinds of properties for a HapticSource, such as loop, priority playback, amplitude multiplication and frequency shift. HapticSource gives you greater flexibility than using HapticController, where you have to specify these properties before playback for each HapticClip you want to play.
In your GameObject you can decide to trigger events associated with the specified HapticSource without using any code.
But you can also write scripts with it, like in the Wobble demo examples below.
...
public virtual void OnPointerExit(PointerEventData data)
{
...
SpringAudioSource.Play();
SpringHapticSource.Play();
}
...
public virtual void SetPitch(float newPitch)
{
SpringAudioSource.pitch = newPitch;
SpringHapticSource.frequencyShift = NiceVibrationsDemoHelpers.Remap(newPitch, 0.3f, 1f, -1.0f, 1.0f);
}
In this case, once the AudioSource gets triggered, the same happens for the HapticSource. We're trying to achieve sync between audio and haptics. For each button pressed on the Wobble demo, a new frequency shift is set for both audio and haptics.
You could also set more properties in code for a HapticSource if you like:
// Set the playback of a haptic clip to loop
SpringHapticSource.loop = true;
// Sets the level of amplitude for a haptic clip, e.g. vibration "strength"
SpringHapticSource.level = 1.1;
// Sets the playback priority of the HapticSource;
// Highest priority corresponds to 0, the lowest to 255
SpringHapticSource.priority = 0;
Setting the priority is important when dealing with multiple HapticSource components. Nice Vibrations only allows playback of a single HapticClip at a time. You might have a HapticSource for player footsteps with a lower priority than a HapticSource associated with an explosion.
// Lowest priority
stepsHapticSource.priority = 255;
// Highest priority
explosionHapticSource.priority = 0;
If they had the same priority, the stepsHapticSource
would be able to
interrupt playback from the explosionHapticSource
.
All of these examples have been done with code, but you could as well just use the Unity Editor. It just depends on how you work with Unity.
In order to reduce repetition fatigue and make the haptics more engaging, you can make use of Real-time modulation of amplitude or frequency to add variations to your haptic clips.
For example repetitive footsteps can be made feel slightly different every time. Or you can make a distant explosion feel less intense based on the proximity to the player.
// Footstep variations
footstepHapticSource.frequencyShift = Random.Range(0.0f, 0.4f);
footstepHapticSource.Play();
Although Nice Vibrations 4 provides a universal interface to play haptics, there are some features and requirements differences from one platform to the next.
The table below summarizes the iPhone haptic capabilities based on OS version and device model.
Haptic capabilities | Minimum requirements |
---|---|
Basic Haptic capabilities | iPhone 7 or newer iOS 11 or newer |
Advanced capabilities and Real-time capabilities |
iPhone 8 or newer iOS 13 or newer |
The table below summarizes the available supported features based on the type of capabilities that an iPhone has:
Features | Basic capabilities |
Advanced Capabilities |
---|---|---|
Play Constant | ❌ | ✅ |
Play Emphasis | ✅ | ✅ |
Play Preset | ✅ | ✅ |
Play Haptic Clip | ❌ | ✅ |
Stop | ❌ | ✅ |
Seek | ❌ | ✅ |
Loop | ❌ | ✅ |
Real-time amplitude modulation | ❌ | ✅ |
Real-time frequency modulation | ❌ | ✅ |
In general, there aren't any limitations when the iPhone has advanced haptic
capabilities. However, if the device only has
basic haptics, the method
HapticPatterns.PlayConstant()
only works when a fallback haptic
preset is provided.
The table below summarizes Android devices haptic capabilities based on OS version and device model.
Haptic capabilities | Minimum requirements |
---|---|
Basic Haptic capabilities | Android API level 17 (Jelly Bean) Have an actuator |
Advanced capabilities | Android API level 26 (Oreo) Have an actuator that allows for amplitude control |
Real time capabilities | Not available |
The table below summarizes the available supported features based on the type of capabilities that an Android phone has:
Features | Basic capabilities |
Advanced Capabilities |
---|---|---|
Play Constant | ✅ | ✅ |
Play Emphasis | ✅ emulated | ✅ emulated |
Play Preset | ✅ | ✅ |
Play Haptic Clip | ❌ | ✅ |
Stop | ✅ | ✅ |
Seek | ❌ | ✅ |
Loop | ❌ | ✅ |
Real-time amplitude modulation | ❌ | ❌ |
Real-time frequency modulation | ❌ | ❌ |
Currently, Android has some playback limitations compared to iOS:
Features | Limitations |
---|---|
HapticController.SetFrequencyShift() HapticSource.frequencyShift and HapticClip with a frequency envelope |
Won't do anything on Android phones. Currently none of the Android APIs allow you to manipulate how fast the phone actuator should vibrate. |
HapticPatterns.PlayEmphasis() and HapticClip with emphasis points |
We achieve emphasis haptics on iOS 13+ with a special type of haptic provided by the CoreHaptics API called a "transient." Android currently doesn't have this type of haptic, so we emulate emphasized haptics within the continuous haptic output. |
HapticController.Loop HapticSource.loop
|
Looping on Android has issues that we have reported to the Android team. This issue is now fixed on Android 12. Older versions, however, will still have looping limitations. The effect will feel choppy in longer haptic clips, but it might be good enough in short ones. |
To play haptics on gamepads, Nice Vibrations 4 depends on Unity's newest Input System package. For Nice Vibrations 4 to work with gamepads, you need to do the following to your project:
- Install and import the Input System package
- Enable it in in your project player settings, "Active Input Handling". We
recommend choosing "Both", as seen in the image below
This is all Nice Vibrations 4 needs so you can start playing haptics to gamepads that support rumble through Unity's Input System on Windows & Mac. For more information about supported devices, please check the Input Systems's documentation Rumble section.
For consoles, you need to install the console-specific Input System packages in your project.
When gamepads have Rumble supported by the Unity's Input System, by default they support "all" haptic capabilities with limitations. Most gamepad actuator technology is based on ERM actuators which cannot produce HD haptics. Check the limitations section for more details.
There is no haptic playback support for gamepad controllers connected to iOS or Android devices.
If you want you disable gamepad support, which will also reduce the size of
HapticClip objects, you can set a platform custom define
NICE_VIBRATIONS_DISABLE_GAMEPAD_SUPPORT
in the player settings "Scripting
define
symbols".
Make sure to re-import all of your haptic clip assets after this change.
The APIs of Nice Vibrations 4, such as HapticSource, HapticController and HapticPatterns, will automatically play the haptics on a gamepad once a gamepad is connected. However, you might have multiple gamepads connected to a game and need set in which gamepad haptics will be played. To do this, you need to call a gamepad specific method from the GamepadRumbler class.
GamepadRumbler.SetCurrentGamepad(2);
In this case, the method would trigger vibrations to the 3rd gamepad. For more details check the API documentation.
If gamepads are supported in a platform, they have the following features:
Features | Supported |
---|---|
Play Constant | ✅ |
Play Emphasis | ✅ emulated |
Play Preset | ✅ |
Play Haptic Clip | ✅ |
Stop | ✅ |
Seek | ❌ |
Loop | ❌ |
Real-time amplitude modulation | ✅ |
Real-time frequency modulation | ❌ |
Mobile device support | ❌ |
In general, the quality of gamepad haptics is not the best due to the actuator technology available in most gamepads in the market. Also, the Input System API calls need to be done from the main thread which means that the timer resolution to play a haptic clip is at best 1/60 FPS.
This means that haptic clips with a lot detail won't feel the best in gamepads. For instance, if they feel great in iOS, make sure to manage your expectations on how they will feel on gamepads.
We plan to improve the quality of playback of haptic clips in gamepads in future releases by automatically adjusting the number of breakpoints that can be played by the Input System.
Besides this, there are currently some features with limitations for gamepads:
Features | Limitations |
---|---|
HapticController.clipFrequencyShift HapticSource.frequencyShift |
Currently it doesn't do anything on gamepads. |
HapticController.PlayConstant() |
Currently, changing the frequency parameter in this method won't do anything. This depends on HapticController.clipFrequencyShift which is not available. |
Linux support | N/A |
Multiple gamepad parallel haptic playback | N/A |
Support for gamepad controllers connected to a mobile phone | N/A |
Here is a list of what some of the methods from Nice Vibrations 3.9 look like in Nice Vibrations 4.
Version 3.9 | Version 4.0 |
---|---|
MMNVAndroid.AndroidSDKVersion() |
DeviceCapabilities.platformVersion |
MMVibrationManager.iOSVersion() MMNViOS.ComputeiOSVersion()
|
DeviceCapabilities.platformVersion |
MMVibrationManager.iOS() |
if (DeviceCapabilities.platform == RuntimePlatform.IPhonePlayer) |
MMVibrationManager.Android() |
if (DeviceCapabilities.platform == RuntimePlatform.Android) |
MMNVAndroid.AndroidHasVibrator() MMNVAndroid.AndroidHasAmplitudeControl()
|
No replacement as fine-grained as this. Use DeviceCapabilities.meetsAdvancedRequirements to check if the device can play back .haptic clips, which needs a vibrator with amplitude control. |
MMNViOS.iOSHapticsSupported() |
DeviceCapabilities.meetsAdvancedRequirements |
Version 3.9 | Version 4.0 |
---|---|
MMNViOSCoreHaptics.OnHapticPatternStopped |
HapticController.PlaybackStopped Works also on Android |
MMNViOSCoreHaptics.OnHapticPatternError |
Errors are swallowed and printed to console. No exceptions are thrown in case of error. |
MMNViOSCoreHaptics.OnHapticPatternReset |
N/A |
Version 3.9 | Version 4.0 |
---|---|
Playing advanced haptic patterns from assets MMVibrationManager.AdvancedHapticPattern(..);
|
HapticController.Play(HapticClip clip) Currently, only .haptic files are supported. |
Stopping haptics playback MMVibrationManager.StopAllHaptics() MMVibrationManager.StopContinuousHaptic() MMVibrationManager.SetHapticsActive(bool)
|
HapticController.Stop() bool HapticController.hapticsEnabled
|
MMVibrationManager.TransientHaptic(..) |
HapticPatterns.PlayEmphasis(float amplitude, float frequency) The amplitude and frequency parameters are the same for Android and iOS, and cannot be specified separately. Amplitude and frequency will have no effect on Android. |
MMVibrationManager.ContinuousHaptic(..) |
HapticPatterns.PlayConstant(float amplitude, float frequency, float duration) The amplitude and frequency parameters are the same for Android and iOS, and cannot be specified separately. Fallback for older versions of iOS currently not available. |
MMVibrationManager.UpdateContinuousHaptic(float intensity, float sharpness, ..) |
HapticController.SetAmplitudeMultiplication(intensity) HapticController.SetFrequencyShift(sharpness)
|
MMVibrationManager.Haptic(..) |
Coming soon |
MMVibrationManager.Vibrate() |
Currently there is no basic method to trigger a simple vibration. You can use HapticPatterns class methods to achieve a similar experience. |
MMVibrationManager.Remap(..) |
N/A |
Playing multiple haptics in parallel on iOS | Playing multiple clips in parallel is not supported. One way to deal with multiple clips that potentially play at the same time is to use priorities. See this section to know more about how you can deal with this using HapticSource. |
Version 3.9 | Version 4.0 |
---|---|
MMNVRumble.GetGamepad(..) |
N/A |
MMNVRumble.Rumble(..) |
HapticController.Play() and every other method to trigger haptics playback. |
MMNVRumble.RumbleContinuous(..) |
HapticPatterns.PlayConstant() This will not change frequency values as explained in gamepad specifics section |
MMNVRumble.StopRumble() |
HapticController.Stop() |
MMNVRumble.PauseRumble() |
N/A |
MMNVRumble.ResumeRuble() |
N/A |
On iOS, sometimes vibrations (other than emphasis vibrations) do not work for the first 30 seconds after triggering the first vibration. This is a known iOS issue: CoreHaptics sometimes fails to trigger a vibration right after it is initialized. To work around this issue, initialize Nice Vibrations during startup, leaving enough time between initialization and triggering the first vibration for CoreHaptics to work properly. There are two ways to do this:
-
Place a HapticReceiver in your scene. It will take care of initializing Nice Vibrations when the scene loads.
-
If you don't want to place a HapticReceiver in your scene, you can also call
HapticController.Init()
yourself in theAwake()
orStart()
method of one of your scene's GameObject's MonoBehaviour.
When Building for iOS, I receive an error message about "no such file or directory for LofeltHaptics.framework"
error: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS**.sdk/NiceVibrations/Plugins/iOS/LofeltHaptics.framework: No such file or directory (in target 'Unity-iPhone' from project 'Unity-iPhone')
ℹ️ This issue was fixed on Nice Vibrations 4.0.1. We recommend that you update to 4.0.1 where the post build script was removed and there's no need to do any of the steps below.
This issue occurred in version 4.0.0 if the NiceVibrations asset folder was not placed directly under the Asset's folder of your Unity project.
To solve this, you needed to update the
NiceVibrations/Scripts/Editor/PostBuildScript.cs
script variable
frameworkFolderXcodeProjectPath
with the new path.
For example, if you changed the NiceVibrations asset folder location inside your
Unity Project to FolderExample/NiceVibrations
, you needed to update the
variable below,
const string frameworkFolderXcodeProjectPath = "NiceVibrations/Plugins/iOS";
to match your new path, like you can see below,
const string frameworkFolderXcodeProjectPath = "FolderExample/NiceVibrations/Plugins/iOS";
A workaround to solve this issue is by releasing and initializing the native bindings before and after calling the function to show the advertisement, respectively:
// release haptic binding
LofeltHaptics.Release()
// wait until ad is closed
await ShowRewardedAd();
// initializing haptic binding
LofeltHaptics.Initialize();
At the moment, it's not possible to use Cloud Build with our plug-in out of the box. It's still technically possible, but you'll have to tweak your paths manually, which can get tedious. We recommend you build locally in the meantime.
The Nice Vibrations demo scene needs to be opened with a 2019.4 version of Unity or newer.
This is a known issue with the current version and will be addressed in an upcoming update.