Unity Upgrade v2.6 Guide
Unity Engine Plugin 2.X to v2.6
Note
This guide is meant to help upgrade one’s Unity Plugin v2.X scripts to the SenseGlove Unity Plugin v2.6. If your project is based on older code, or if you’re starting from scratch, you won’t need to go through these steps.
The SenseGlove Unity Plugin v2.6 introduces Nova 2.0 support. But with that, it also introduces some breaking changes to our haptic- and calibration method(s). These changes are made to (hopefully) improve the ease of use of the SenseGlove APIs.
For example, if you want to send a vibration of 0.5 seconds with an amplitude of 0.8 to the index finger, instead of calling
myHapticGlove.SendCmd(new SG_TimedBuzzCmd(new SG_BuzzCmd(SGCore.Fingers.Index, 0.8f), 0.5f);
You can now call
myHapticGlove.SendVibrationCmd(VibrationLocation.IndexFingerTip, 0.8f, 0.5f, 170.0f);
And you can even set the desired frequency (supported by Nova 2.0, and Nova 1.0 with firmware update)!
Calibration is now running inside the API, and will eventually be running on the device(s) themselves - removing the need for calibration scripts inside one’s scene.
Importing the plugin
Before you make any upgrade, make sure your project is backed up / committed / copied.
As with any update, we recommend deleting your project’s SenseGlove.
If you’ve been running the project before, you might need to restart the editor to delete SGConnect.dll - since Unity keeps C++ resources like this in memory.
Import the new SenseGlove Unity Package into your project
You may see a bunch of compiler errors. Don’t panic; here’s a list of the most common changes:
Major Changes
Sticking to public methods as those are the ones user by 3rd party scripts.
IHandFeedbackDevice Interface Functions
Removed internal SenseGlove Classes as parameters. Merged Thumper- and finger vibration commands. Vibration location is now determined by an enum. Renamed functions to be more indicative of what they actually do: SendCmd(FFBCmd) would acutally queue the command to be flushed at the end of the frame (mixed with other FFB signals).
public void SendCmd(SG_FFBCmd ffb)
Replaced with
/// <summary> Tell the device to queue up a Force-Feedback command to this particular finger </summary>
void QueueFFBCmd(SGCore.Finger finger, float value01);
/// <summary> Tell the device to queue up Force-Feedback to several fingers. Levels 0...1 from Thumb = 0 to Pinky = 4. </summary>
void QueueFFBCmd(float[] values01);
This will place the FFB levels for one or more fingers in a queue that will be flushed during LateUpdate. If the FFB of a particular finger is set multiple times in a frame, the highest received force-level is used.
The glove will continue to hold this force, until otherwise specified.
Associated errors
error CS0234: The type or namespace name 'SG_FFBCmd' does not exist in the namespace 'SGCore.Haptics' (are you missing an assembly reference?)
public void SendCmd(SGCore.Haptics.SG_TimedBuzzCmd fingerCmd)
Replaced with
/// <summary> Send a timed command to a particular location on the hand. If the device supports said location, it will fire a haptic effect </summary>
void SendVibrationCmd(VibrationLocation location, float amplitude, float duration, float frequency);
A faster way to call vibration commands without needing to create two SGCore objects. If the device supports setting the frequency, the parameter is used. If not, it is ignored. Amplitude is set as a value between 0 … 1. Duration is set in seconds, with a max of 1,5 seconds.
As opposed to the force-feedback commands, the vibrotactile commands are sent to the glove right away. If another effect is already playing, it will be replaced with this one.
/// <summary> All available glove vibration locations. </summary>
public enum VibrationLocation
{
Unknown,
Thumb_Tip,
Index_Tip,
Middle_Tip,
Ring_Tip,
Pinky_Tip,
Palm_IndexSide,
Palm_PinkySide,
/// <summary> Play this Haptic Effect on the whole hand. For General Hand Feedback. </summary>
WholeHand
}
Associated errors
error CS0234: The type or namespace name 'SG_TimedBuzzCmd' does not exist in the namespace 'SGCore.Haptics' (are you missing an assembly reference?)
public void SendCmd(SGCore.Haptics.TimedThumpCmd wristCmd)
The word “thumper” is an internal name for the actuator on the back of the hand. Which was never clearly documented, and with the Nova 2.0, we have two possible vibration locations.
Merged into
void SendVibrationCmd(VibrationLocation location, float amplitude, float duration, float frequency);
See also: SendCmd(SGCore.Haptics.SG_TimedBuzzCmd fingerCmd) above.
We recommend using the VibrationLocation.WholeHand for general hand vibrations to ensure compatibility with Nova 1.0 and 2.0, otherwise, you may need to consider a switch case (discussed later).
Associated errors
error CS0234: The type or namespace name 'TimedThumpCmd' does not exist in the namespace 'SGCore.Haptics' (are you missing an assembly reference?)
public void SendCmd(SG_Waveform waveform)
“SG Waveform” was our way to create vibrations though the Unity Animation Curves - stored in a ScriptableObject to re-use across one’s project. They offer a lot of freedom in terms of creating the amplitude, but this curve is only sampled in 11-14ms intervals, resulting in it missing small changes.
It is still possible to use this for the Nova 1.0, but these will be discontinued in the Nova 2.0, to be replaced with our new “Custom Waveforms”.
replaced with
public void SendLegacyWaveform(SG_Waveform waveform);
public void SendLegacyWaveform(SG_Waveform waveform, float amplitude, float duration, VibrationLocation location);
Instead of having a thumb, index, middle, ring, pinky, and wrist boolean, each SG_Waveform now has a VibrationLocation enum called intendedMotor to determine which actuator is triggered.
You can now also override the ScriptableObject’s other parameters with an overload function.
public void SendCmd(ThumperWaveForm waveform)
Originally meant as a way to stream an SG_Waveform to the thumper, this command has been merged into SendLegacyWaveform (see above)
We recommend using the VibrationLocation.WholeHand for general hand vibrations to ensure compatibility with Nova 1.0 and 2.0, otherwise, you may need to consider a switch case (discussed later).
Associated errors
error CS0234: The type or namespace name 'ThumperWaveForm' does not exist in the namespace 'SGCore.Haptics' (are you missing an assembly reference?)
public void SendCmd(SG_NovaWaveform customWaveform, SGCore.Nova.Nova_VibroMotor location)
Originally only available to Nova 1.0 Gloves, we’ve refactored this function to be compatible with any glove, as long as it has a motor on the desired location.
Renamed the SG_NovaWaveform scriptableobjects to SG_CustomWaveform to reflect this.
Replaced the SGCore.Nova.Nova_VibroMotor with VibrationLocation for consistency.
Replaced with
public void SendCustomWaveform(SG_CustomWaveform customWaveform, VibrationLocation location)
SG_HapticGlove Calibration Changes
In addition to the changes to the IHandFeedbackDevice interface, the SG_HapticGlove now also has some changes to its calibration methods: Sensor calibration now runs ‘live’ inside the API, rather than having to be managed by an SG_CalibrationSequence. This means you’re no longer obligated to run the Calibration void inside the simulation (though it is still possible).
public bool CalibrationLocked
Removed because calibration is no longer managed within the simulation by a SG_CalibrationSequence.
public SGCore.Calibration.CalibrationStage GetCalibrationStage()
Moved into an accessor, and made into a more generic “HapticGlove Calibration State”
SGCore.HG_CalibrationState state = myGlove.LastCalibrationState;
With the following parameters:
// No device connected or undefined state
Unknown = 0,
// One or more sensors still need to move...
MoveFingers = 1,
// All sensors have moved, now we just need to lock in calibration
AllSensorsMoved = 2,
// Calibration is locked in. Done collecting Data. calibration won't change anymore
CalibrationLocked = 3
You can also subscribe to the SG_HapticGlove’s CalibrationStateChanged event.
public bool StartCalibration(SG_CalibrationSequence sequence)
This would normally lock calibration to a Sequence. However, it has been replaced with
public bool StartCalibration();
Which returns true if the device is connected and calibration was reset.
public bool CompleteCalibration(SG_CalibrationSequence sequence)
This would unlock calibration from a sequence. It was removed since sequences no longer manage the calibration. Calibration can now be ended through the following function:
public bool CompleteCalibration();
New Nova 2.0 Functions
Active Contact Feedback a.k.a. Wrist Squeeze
The Nova 2.0 comes with an actuated wrist strap that can squeeze the hand palm.
You can set the “squeeze level” of the Nova 2.0 - as a value between 0 .. 1 - through the following functions:
/// <summary> Set the amount of squeeze feedback desired on the wrist. Where 0 is no squeeze, and 1 is full squeeze force. </summary>
void QueueWristSqueeze(float squeezeLevel01);
/// <summary> Stops any active squeeze effects on the wrist. </summary>
void StopWristSqueeze();
Like with the Force-Feedback motors, one adds the desired level to a queue that is to be flushed at the end of the frame.
Vibrating the new actuators
The Nova 2.0’s wrist strap now comes with integrated vibration motors; one closer towards the index finger, and another closer to the pinky. These can be vibrated through the new SendVibrationCmd function, with the appropriate VibrationLocation enum:
myGlove.void SendVibrationCmd(VibrationLocation.Palm_IndexSide, 1.0f, 0.2f, 170.0f);
myGlove.void SendVibrationCmd(VibrationLocation.Palm_PinkySide, 1.0f, 0.2f, 170.0f);
Haptics for both Nova 1.0 and Nova 2.0
While Both Nova 1.0 and 2.0 have vibration motors on the index fingertip and thumb, that is where the similarities end.
The Nova 1.0 has a single, powerful VCA on the back of the hand, nicknamed “the Thumper”.
The Nova 2.0 has two smaller, less powerful LRAs that touch the hand palm
These result in vastly different haptic experiences. An aplitude of 1.0f for the Nova 1.0’s thumper results in a loud and intense vibration, while an amplitude of 1.0 on the Nova 2 palm actuaters are much more subtle.
To ensure your wrist vibration haptics feel right for each glove, we reccomend defining them specifically for each device if available:
public void PlayWristPulse()
{
if (myGlove.DeviceType == SGCore.DeviceType.NOVA) //Nova 1.0
{
myGlove.SendVibrationCmd(VibrationLocation.Palm_IndexSide, 0.25f, 0.2f, 80.0f);
}
else if (myGlove.DeviceType == SGCore.DeviceType.NOVA_2) //Nova 2.0
{
myGlove.void SendVibrationCmd(VibrationLocation.Palm_IndexSide, 1.0f, 0.2f, 170.0f);
myGlove.void SendVibrationCmd(VibrationLocation.Palm_PinkySide, 1.0f, 0.2f, 170.0f);
}
}