Issue with TriggerHapticPulse (Vive Controller)

Hello,

I’m trying to use TriggerHapticPulse within an if statement. I’ve set the duration to values 500 - 3999 and yet the only thing I get at run time is a blip of haptic feedback. Out of curiosity, I’ve placed TriggerHapticPulse within the Update method and as expected I get a steady vibration (as the statement is called every frame). My question is what am I doing wrong and/or how can I make TriggerHapticPulse last 1 second or any other duration longer than a fraction of a second?

Here is my script:

SteamVR_TrackedObject trackedObj;
SteamVR_Controller.Device device;

void Awake ()
    {
        trackedObj = GetComponent<SteamVR_TrackedObject>();
    }

void FixedUpdate() 
    {
        device = SteamVR_Controller.Input((int)trackedObj.index);
    }

void Update ()
    {
        rumbleController ();
    }

void rumbleController ()
    {
        if (device.GetPressDown (SteamVR_Controller.ButtonMask.Grip)
        {
            device.TriggerHapticPulse (1000);
        }

Here is the solution:

void rumbleController ()
    {
        if (device.GetPressDown (SteamVR_Controller.ButtonMask.Grip)
        {
            StartCoroutine(LongVibration(1,3999));
        }
    }

IEnumerator LongVibration(float length, float strength)
    {
        for(float i = 0; i < length; i += Time.deltaTime)
        {
            device.TriggerHapticPulse((ushort)Mathf.Lerp(0, 3999, strength));
            yield return null;
        }
    }
3 Likes

I know this was posted two years ago but since I came across it in a search and others likely will too, I thought i’d point out a couple errors in the code. The fact that “strength” is used as the third variable in a lerp and it is not changing during the duration of the for loop means that the value inside TriggerHapticPulse will always be the same as long as strength is more than 1 (it will always be 3999).

This will create a full max strength pulse for the duration that you set with the “length”. For your purposes, I don’t think you need the lerp at all and you can just make strength a ushort and use it directly.

void rumbleController ()
    {
        if (device.GetPressDown (SteamVR_Controller.ButtonMask.Grip)
        {
           StartCoroutine(LongVibration(1,3999));
        }
    }


IEnumerator LongVibration(float length, ushort strength)
    {
        for(float i = 0; i < length; i += Time.deltaTime)
        {
            device.TriggerHapticPulse(strength);
            yield return null; //every single frame for the duration of "length" you will vibrate at "strength" amount
        }
    }

The new code will do what you want.

In my game I wanted to have a little fun with how the vibrations felt so I added a couple pulsing modes for notifications on the main character’s spy watch. I’ll post one with options below: alter it how you like, and if you’re interested in seeing more VR development, catch me on Twitch full time making my new game Plvnkvr :

public void VibrateController(Hand hand, float timer, ushort amount)
{
      StartCoroutine(VibrateControllerContinuous(hand, timer, amount));
}


IEnumerator VibrateControllerContinuous(Hand hand, float timer, ushort amount)
{
      float pulse_length = 0.5f;
      bool saw_tooth_right = true;
      // if true the pulse will happen in a sawtooth pattern like this /|/|/|/|
      // else it will happen opposite like this |\|\|\|\
      while (timer > 0)
      {
          if(saw_tooth_right) {hand.controller.TriggerHapticPulse((ushort)((pulse_length - (timer % pulse_length)) * (float)amount)); }
          else { hand.controller.TriggerHapticPulse((ushort)((timer % pulse_length) * (float)amount));}
          hand.controller.TriggerHapticPulse(amount);
          timer -= Time.deltaTime;
          yield return null;
      }
      yield break;
}

EDIT: I edited the answer to add code formatting, whoops!

1 Like

This is great! Thanks so much!

1 Like