Lofelt / NiceVibrations

🎮 🚀 Nice Vibrations and Lofelt Studio SDK source code repository
MIT License
125 stars 17 forks source link

Playing haptics while multiple gamepads are involved causes some haptic clips to play continuously. #32

Open Radicals27 opened 1 year ago

Radicals27 commented 1 year ago

Bug report

Checklist

Environment

Unity 2021.3.9, Windows platform Game is a local co-op game/couch co-op 1-4 players via gamepads.

Goals

We want a reliable method of triggering haptics on individual gamepads. With nice vibrations we are 90% of the way there however there is a bug where raising a haptic event on controller X and then on controller Y will cause X to not stop/clean-up properly.

Steps to Reproduce

Have 2+ controllers with vibration/rumble capacity plugged into the PC. Have controller 1 trigger a haptic event via the calls: GamepadRumbler.SetCurrentGamepad(gamepadID); HapticController.PlayClip(hapticClip); Then have controller 2 trigger a haptic event. This will cause controller 1 (assuming controller 1 was vibrating as controller 2 started its vibration) to continue indefinitely until a new haptic event is called on controller 1.

Expected behavior

Controller 1 and 2's haptic events should not affect each other.

Observed behavior

Controller 2's haptics influenced controller 1's haptics, causing it to play on it's last vibration 'note' forever.

Code Samples & Details

See above for the 2 lines of code we are using. We can confirm the methods are being called correctly. We have identified the issue as being in NiceVibrations HapticController.cs script's Play() method;

if (remainingPlayDuration > 0.0f) { playbackFinishedTimer.Interval = remainingPlayDuration * 1000; playbackFinishedTimer.AutoReset = false; playbackFinishedTimer.Enabled = !isPlaybackLooping; } else { HandleFinishedPlayback(); } there is only one playbackFinishedTimer in this class, so each subsequent call to Play() will not "wrap up" or cleanly finish the previous haptic's "HandleFInishedPlayback()". It will instead just play the next clip and handle it's clean up, leaving the original to play forever.

leohilbert commented 1 month ago

i'm running into the same problem. Did you find a solution to it @Radicals27 ? <3

Edit: I'm debugged it, and I think it's caused by UnityEngine.InputSystem.Gamepad.current jumping around like crazy. On one frame it's the first gamepad, on another frame it's the other one. It would probably be best if I'd manually set the Gamepad to the correct one using Lofelt.NiceVibrations.GamepadRumbler.SetCurrentGamepad. We are a singleplayer game, so it's pretty straight forward. Although I wonder how one would set this up for a multiplayer game. I mean I'd need to somehow link a haptic feedback to the respective PlayerInput/Gamepad

{
    HapticController.hapticsEnabled = true;
    var gamepadIndex = Gamepad.all.IndexOf(x => x == gamepad);
    Debug.LogWarning("Current Gamepad Index: " + gamepadIndex);
    GamepadRumbler.SetCurrentGamepad(gamepadIndex);
}

pRoBlEm SoLvEd 😄