EscapeShooter/My project/Assets/Project Files/Modules/Haptic/Scripts/Runtime/Haptic.cs

161 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
namespace Watermelon
{
/// <summary>
/// Manages haptic feedback across platforms (iOS, Android, WebGL, Editor).
/// <para>Create an instance via <c>new Haptic()</c> (e.g. from <see cref="HapticInitModule"/>) to activate the module,
/// then use the static facade methods to trigger feedback.</para>
/// </summary>
public class Haptic
{
private static Haptic instance;
/// <summary>Predefined light haptic feedback (short, low intensity).</summary>
public static readonly HapticData HAPTIC_LIGHT = new HapticData(0.14f, 0.4f);
/// <summary>Predefined medium haptic feedback.</summary>
public static readonly HapticData HAPTIC_MEDIUM = new HapticData(0.14f, 0.6f);
/// <summary>Predefined strong haptic feedback.</summary>
public static readonly HapticData HAPTIC_HARD = new HapticData(0.14f, 0.8f);
/// <summary>Predefined light haptic pattern.</summary>
public static readonly HapticPattern PATTERN_LIGHT = new HapticPattern("light", new HapticEvent[]
{
new() { Duration = 0.3f, Intensity = 1.0f, Sharpness = 0.0f, StartTime = 0.0f }
});
private bool isActive;
private readonly HapticSave save;
private readonly BaseHapticWrapper wrapper;
/// <summary>Fires when haptic is enabled or disabled.</summary>
public static event SimpleBoolCallback StateChanged;
/// <summary>
/// Whether haptic feedback is currently enabled. Persisted across sessions.
/// Returns <c>false</c> if the module has not been created yet.
/// </summary>
public static bool IsActive
{
get => IsInitialized && instance.isActive;
set
{
if (!IsInstanceExists()) return;
instance.isActive = value;
instance.save.IsActive = value;
SaveController.MarkAsSaveIsRequired();
LogManager.Log($"[Haptic]: State changed: {(value ? "Active" : "Disabled")}", LogCategory.Systems);
StateChanged?.Invoke(value);
}
}
/// <summary>Returns <c>true</c> if an instance has been created.</summary>
public static bool IsInitialized => instance != null;
/// <summary>
/// Creates the haptic module instance, loads saved state and sets up the platform wrapper.
/// The constructor registers itself as the active instance.
/// </summary>
public Haptic()
{
instance = this;
save = SaveController.GetSaveObject<HapticSave>("haptic");
isActive = save.IsActive;
wrapper = GetPlatformWrapper();
if (wrapper == null)
{
LogManager.LogWarning("[Haptic]: Unsupported platform", LogCategory.Systems);
return;
}
wrapper.Init();
wrapper.RegisterPattern(PATTERN_LIGHT);
}
/// <summary>
/// Registers a custom haptic pattern so it can be triggered via <see cref="Play(HapticPattern)"/> or <see cref="Play(string)"/>.
/// </summary>
public static void RegisterPattern(HapticPattern hapticPattern)
{
if (!IsInstanceExists()) return;
if (instance.wrapper == null) return;
instance.wrapper.RegisterPattern(hapticPattern);
}
/// <summary>Plays haptic feedback using a <see cref="HapticData"/> preset.</summary>
public static void Play(HapticData hapticData)
{
Play(hapticData.Duration, hapticData.Intensity);
}
/// <summary>Plays haptic feedback with the given duration (seconds) and intensity (0–1).</summary>
public static void Play(float duration, float intensity = 1.0f)
{
if (!IsActive) return;
if (instance.wrapper == null) return;
if (duration <= 0) return;
instance.wrapper.Play(duration, intensity);
}
/// <summary>Plays a registered <see cref="HapticPattern"/>.</summary>
public static void Play(HapticPattern pattern)
{
if (!IsActive) return;
if (instance.wrapper == null) return;
instance.wrapper.Play(pattern.ID);
}
/// <summary>Plays a registered haptic pattern by its string ID.</summary>
public static void Play(string patternID)
{
if (!IsActive) return;
if (instance.wrapper == null) return;
instance.wrapper.Play(patternID);
}
/// <summary>Releases the module instance and clears all state.</summary>
public static void Unload()
{
instance = null;
StateChanged = null;
}
private static bool IsInstanceExists()
{
if (instance == null)
{
LogManager.LogWarning("[Haptic]: Module is not initialized. Create a Haptic instance first.", LogCategory.Systems);
return false;
}
return true;
}
public static BaseHapticWrapper GetPlatformWrapper()
{
#if UNITY_EDITOR
return new EditorHapticWrapper();
#elif UNITY_IOS
return new IOSHapticWrapper();
#elif UNITY_ANDROID
return new AndroidHapticWrapper();
#elif UNITY_WEBGL
return new WebGLHapticWrapper();
#else
return null;
#endif
}
}
}