using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using System.Runtime.InteropServices;
|
using System;
|
using AOT;
|
|
#if UNITY_IOS
|
using UnityEngine.iOS;
|
#endif
|
|
namespace MoreMountains.NiceVibrations
|
{
|
/// <summary>
|
/// This class handles all iOS haptics specific calls for devices that support the CoreHaptics API (post iOS 13)
|
/// </summary>
|
public static class MMNViOSCoreHaptics
|
{
|
public static event Action OnHapticPatternStopped;
|
public static event Action OnHapticPatternError;
|
public static event Action OnHapticPatternReset;
|
|
private static float _initialContinuousIntensity;
|
private static float _initialContinuousSharpness;
|
|
#if UNITY_IOS && !UNITY_EDITOR
|
[DllImport("__Internal")]
|
private static extern bool MMNViOS_CoreHapticsSupported();
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_CreateEngine();
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_StopEngine();
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_PlayTransientHapticPattern(float intensity, float sharpness, bool threaded);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_PlayContinuousHapticPattern(float intensity, float sharpness, float duration, bool threaded);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_UpdateContinuousHapticPattern(float intensity, float sharpness, bool threaded);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_StopContinuousHaptic();
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_PlayCoreHapticsFromJSON(string jsonString, bool threaded);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_CoreHapticsRegisterHapticEngineFinishedCallback(Action callback);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_CoreHapticsRegisterHapticEngineErrorCallback(Action callback);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_CoreHapticsRegisterHapticEngineResetCallback(Action callback);
|
[DllImport("__Internal")]
|
private static extern void MMNViOS_CoreHapticsSetDebugMode(bool status);
|
#else
|
private static bool MMNViOS_CoreHapticsSupported() { return false; }
|
private static void MMNViOS_CoreHapticsSetDebugMode(bool status) { }
|
private static void MMNViOS_CreateEngine() { }
|
private static void MMNViOS_StopEngine() { }
|
private static void MMNViOS_PlayTransientHapticPattern(float intensity, float sharpness, bool threaded) { }
|
private static void MMNViOS_PlayContinuousHapticPattern(float intensity, float sharpness, float duration, bool threaded) { }
|
private static void MMNViOS_UpdateContinuousHapticPattern(float intensity, float sharpness, bool threaded) { }
|
private static void MMNViOS_StopContinuousHaptic() { }
|
private static void MMNViOS_PlayCoreHapticsFromJSON(string jsonString, bool threaded) { }
|
private static void MMNViOS_CoreHapticsRegisterHapticEngineFinishedCallback(Action callback) { }
|
private static void MMNViOS_CoreHapticsRegisterHapticEngineErrorCallback(Action callback) { }
|
private static void MMNViOS_CoreHapticsRegisterHapticEngineResetCallback(Action callback) { }
|
#endif
|
|
/// <summary>
|
/// On construction we initialize our haptic engine
|
/// </summary>
|
static MMNViOSCoreHaptics()
|
{
|
MMNViOS_CoreHapticsRegisterHapticEngineFinishedCallback(HapticStoppedCallback);
|
MMNViOS_CoreHapticsRegisterHapticEngineErrorCallback(HapticsErrorCallback);
|
MMNViOS_CoreHapticsRegisterHapticEngineResetCallback(HapticsResetCallback);
|
}
|
|
/// <summary>
|
/// Plays a core haptics pattern from a JSON string that matches the AHAP format
|
/// </summary>
|
/// <param name="jsonString"></param>
|
public static void PlayCoreHapticsFromJSON(string jsonString, bool threaded = false)
|
{
|
MMNViOS_PlayCoreHapticsFromJSON(jsonString, threaded);
|
}
|
|
/// <summary>
|
/// Plays a transient haptic pattern of the specified intensity and sharpness.
|
/// Transient haptics are very short haptic patterns.
|
/// </summary>
|
/// <param name="intensity"></param>
|
/// <param name="sharpness"></param>
|
public static void PlayTransientHapticPattern(float intensity, float sharpness, bool threaded = false)
|
{
|
MMNViOS_PlayTransientHapticPattern(intensity, sharpness, threaded);
|
}
|
|
/// <summary>
|
/// Plays a continuous haptic at the specified intensity and sharpness for the specified duration
|
/// The coroutineMonobehaviour parameter is optional, only send that if you intend to raise this specific continuous pattern's intensity higher than its
|
/// initial value
|
/// </summary>
|
/// <param name="intensity"></param>
|
/// <param name="sharpness"></param>
|
/// <param name="duration"></param>
|
/// <param name="coroutineMonobehaviour"></param>
|
public static void PlayContinuousHapticPattern(float intensity, float sharpness,
|
float duration, MonoBehaviour coroutineMonobehaviour = null, bool threaded = false)
|
{
|
if (intensity < 0.01f)
|
{
|
intensity = 0.01f;
|
}
|
|
_initialContinuousIntensity = intensity;
|
_initialContinuousSharpness = sharpness;
|
|
if (coroutineMonobehaviour != null)
|
{
|
_initialContinuousIntensity = 1f;
|
MMNViOS_PlayContinuousHapticPattern(1f, sharpness, duration, threaded);
|
coroutineMonobehaviour.StartCoroutine(ContinuousHapticPatternCoroutine(intensity, sharpness, threaded));
|
}
|
else
|
{
|
MMNViOS_PlayContinuousHapticPattern(intensity, sharpness, duration, threaded);
|
}
|
}
|
|
/// <summary>
|
/// This coroutine waits for a frame and returns intensity to its normal value
|
/// </summary>
|
/// <param name="intensity"></param>
|
/// <param name="sharpness"></param>
|
/// <returns></returns>
|
public static IEnumerator ContinuousHapticPatternCoroutine(float intensity, float sharpness, bool threaded = false)
|
{
|
yield return null;
|
MMNViOS_UpdateContinuousHapticPattern(intensity, sharpness, threaded);
|
}
|
|
/// <summary>
|
/// This method lets you update the intensity and sharpness of a continuous haptics as it's playing.
|
/// Note that this one is a direct implementation of Apple's native method that serves that same purpose, and
|
/// the way it works can be confusing, as instead of just setting the value, it multiplies and adds like so :
|
/// Sending a dynamic parameter for intensity multiplies the original pattern’s event intensity by the dynamic parameter value.
|
/// Sending a dynamic parameter for sharpness adds the dynamic parameter value to the original pattern’s event sharpness.
|
/// If you'd rather not have to do weird maths to just set two values, you can use
|
/// the UpdateContinuousHapticPatternRational method, which will handle that for you.
|
/// </summary>
|
/// <param name="intensity"></param>
|
/// <param name="sharpness"></param>
|
public static void UpdateContinuousHapticPattern(float intensity, float sharpness, bool threaded = false)
|
{
|
MMNViOS_UpdateContinuousHapticPattern(intensity, sharpness, threaded);
|
}
|
|
/// <summary>
|
/// This method lets you update the intensity and sharpness of a continuous haptics as it's playing.
|
/// It simply sets the intensity and sharpness values to the ones set in parameters
|
/// Just note that due to limitations in Apple's implementation, the intensity can't go higher than its initial value.
|
/// The only way to bypass that is to pass a monobehaviour to PlayContinuousHapticPattern when calling it
|
/// </summary>
|
/// <param name="intensity"></param>
|
/// <param name="sharpness"></param>
|
public static void UpdateContinuousHapticPatternRational(float intensity, float sharpness, bool threaded = false)
|
{
|
if (_initialContinuousIntensity < 0.01f)
|
{
|
_initialContinuousIntensity = 0.01f;
|
}
|
|
float newIntensity = intensity / _initialContinuousIntensity;
|
float newSharpness = sharpness - _initialContinuousSharpness;
|
|
MMNViOS_UpdateContinuousHapticPattern(newIntensity, newSharpness, threaded);
|
}
|
|
/// <summary>
|
/// Stops all running or continuous haptic patterns
|
/// </summary>
|
public static void StopHapticPatterns()
|
{
|
MMNViOS_StopContinuousHaptic();
|
}
|
|
/// <summary>
|
/// Stops the haptic engine entirely, cutting short any AHAP or transient that may have been playing
|
/// </summary>
|
public static void CreateEngine()
|
{
|
MMNViOS_CreateEngine();
|
}
|
|
/// <summary>
|
/// Stops the haptic engine entirely, cutting short any AHAP or transient that may have been playing
|
/// </summary>
|
public static void StopEngine()
|
{
|
MMNViOS_StopEngine();
|
}
|
|
/// <summary>
|
/// Sets the debug mode to true or false.
|
/// While debug mode is active, pretty much every haptic call will output a log in the console.
|
/// Useful when debugging without a device
|
/// </summary>
|
/// <param name="newStatus"></param>
|
public static void SetDebugMode(bool newStatus)
|
{
|
MMNViOS_CoreHapticsSetDebugMode(newStatus);
|
}
|
|
/// <summary>
|
/// Returns true if CoreHaptics are supported, false otherwise
|
/// </summary>
|
/// <returns></returns>
|
public static bool CoreHapticsSupported()
|
{
|
return MMNViOS_CoreHapticsSupported();
|
}
|
|
|
/// <summary>
|
/// Triggers the haptics stopped callback
|
/// </summary>
|
#if UNITY_IOS
|
[MonoPInvokeCallback(typeof(Action))]
|
#endif
|
private static void HapticStoppedCallback()
|
{
|
OnHapticPatternStopped?.Invoke();
|
}
|
|
/// <summary>
|
/// Triggers the haptics error callback
|
/// </summary>
|
#if UNITY_IOS
|
[MonoPInvokeCallback(typeof(Action))]
|
#endif
|
private static void HapticsErrorCallback()
|
{
|
OnHapticPatternError?.Invoke();
|
}
|
|
/// <summary>
|
/// Triggers the haptics reset callback
|
/// </summary>
|
#if UNITY_IOS
|
[MonoPInvokeCallback(typeof(Action))]
|
#endif
|
private static void HapticsResetCallback()
|
{
|
OnHapticPatternReset?.Invoke();
|
}
|
}
|
}
|