void TurnEffectOn()
    {
        if (HapticDevice == null)
        {
            return;                                             //If there is no device, bail out early.
        }
        // If a haptic effect has not been assigned through Open Haptics, assign one now.
        if (FXID == -1)
        {
            FXID = HapticPlugin.effects_assignEffect(HapticDevice.configName);

            if (FXID == -1)             // Still broken?
            {
                Debug.LogError("Unable to assign Haptic effect.");
                return;
            }
        }

        // Send the effect settings to OpenHaptics.
        double[] pos = { 0.0, 0.0, 0.0 };       // Position (not used for vibration)
        double[] dir = { 0.0, 1.0, 0.0 };       // Direction of vibration

        HapticPlugin.effects_settings(
            HapticDevice.configName,
            FXID,
            0.33,                                                    // Gain
            0.33,                                                    // Magnitude
            300,                                                     // Frequency
            pos,                                                     // Position (not used for vibration)
            dir);                                                    //Direction.

        HapticPlugin.effects_type(HapticDevice.configName, FXID, 4); // Vibration effect == 4

        HapticPlugin.effects_startEffect(HapticDevice.configName, FXID);
    }
    //!  Update() is called once per frame.
    //!
    //! This function
    //! - Determines if a haptic stylus is inside the collider
    //! - Updates the effect settings.
    //! - Starts and stops the effect when appropriate.
    void Update()
    {
        // Find the pointer to the collider that defines the "zone".
        Collider collider = gameObject.GetComponent <Collider>();

        if (collider == null)
        {
            Debug.LogError("This Haptic Effect Zone requires a collider");
            return;
        }

        // Update the World-Space vectors
        focusPointWorld = transform.TransformPoint(Position);
        directionWorld  = transform.TransformDirection(Direction);

        // Update the effect seperately for each haptic device.
        for (int ii = 0; ii < devices.Length; ii++)
        {
            HapticPlugin device       = devices [ii];
            bool         oldInTheZone = inTheZone[ii];
            int          ID           = FXID [ii];

            // If a haptic effect has not been assigned through Open Haptics, assign one now.
            if (ID == -1)
            {
                FXID [ii] = HapticPlugin.effects_assignEffect(devices [ii].configName);
                ID        = FXID [ii];

                if (ID == -1)                 // Still broken?
                {
                    Debug.LogError("Unable to assign Haptic effect.");
                    continue;
                }
            }

            // Determine if the stylus is in the "zone".
            Vector3 StylusPos = device.stylusPositionWorld;             //World Coordinates
            Vector3 CP        = collider.ClosestPoint(StylusPos);       //World Coordinates
            devicePoint[ii] = CP;
            delta[ii]       = (CP - StylusPos).magnitude;

            //If the stylus is within the Zone, The ClosestPoint and the Stylus point will be identical.
            if (delta[ii] <= Mathf.Epsilon)
            {
                inTheZone [ii] = true;

                // Convert from the World coordinates to coordinates relative to the haptic device.
                Vector3  focalPointDevLocal = device.transform.InverseTransformPoint(focusPointWorld);
                Vector3  rotationDevLocal   = device.transform.InverseTransformDirection(directionWorld);
                double[] pos = { focalPointDevLocal.x, focalPointDevLocal.y, focalPointDevLocal.z };
                double[] dir = { rotationDevLocal.x, rotationDevLocal.y, rotationDevLocal.z };

                double Mag = Magnitude;

                if (device.isInSafetyMode())
                {
                    Mag = 0;
                }

                // Send the current effect settings to OpenHaptics.
                HapticPlugin.effects_settings(
                    device.configName,
                    ID,
                    Gain,
                    Mag,
                    Frequency,
                    pos,
                    dir);
                HapticPlugin.effects_type(
                    device.configName,
                    ID,
                    (int)effectType);
            }
            else
            {
                inTheZone [ii] = false;

                // Note : If the device is not in the "Zone", there is no need to update the effect settings.
            }

            // If the on/off state has changed since last frame, send a Start or Stop event to OpenHaptics
            if (oldInTheZone != inTheZone [ii])
            {
                if (inTheZone [ii])
                {
                    HapticPlugin.effects_startEffect(device.configName, ID);
                }
                else
                {
                    HapticPlugin.effects_stopEffect(device.configName, ID);
                }
            }
        }
    }