public AntStickBridge(AntStick antStick, BikeData bikeData)
        {
            lastAntStick = antStick;

            this.antStick = antStick;
            this.bikeData = bikeData;

            if (!ThreadHelper.SingletonCheck("AntStickBridge"))
            {
                return;
            }

            antStick.OnStateChange += delegate(object sender, AntStick.StateChangeEventArgs e)
            {
                ThreadHelper.Singleton.PerformActionOnMainThread(() => AntStickStateChange(sender, e));
            };

            PowerOnlyDataPage.OnReceived += delegate(object sender, EventArgs e)
            {
                ThreadHelper.Singleton.PerformActionOnMainThread(() => PowerOnlyReceived(sender, e));
            };

            WheelTorqueDataPage.OnReceived += delegate(object sender, EventArgs e)
            {
                ThreadHelper.Singleton.PerformActionOnMainThread(() => WheelTorqueReceived(sender, e));
            };
        }
    /// <summary>
    /// The standard Unity Start method.
    /// </summary>
    void Start()
    {
        // Set the initial position and rotation; set the character controller.
        initialPosition          = transform.position;
        initialRotation          = transform.rotation;
        this.characterController = this.GetComponent <CharacterController>();

        // Reset position (altitude) and heading.
        this.ResetPositionAndHeadingToTransform();

        // Get a new BikeData object.
        bikeData = new BikeData();

        #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
        // Try to start Ant.
        try
        {
            this.antStick       = new AntStick();
            this.antStickBridge = new AntStickBridge(antStick, bikeData);
            this.antStick.Start();
        }
        catch (Exception ex)
        {
            Debug.LogWarningFormat("[BikeController] Exception while loading Ant.\n{0}", ex.Message);
        }

        // Try to start the XSens Gyro.
        try
        {
            this.xsensGyro       = new XSensGyro();
            this.xsensGyroBridge = new XSensGyroBridge(xsensGyro, this);
            this.xsensGyro.Start();
            // We have to wait after starting the gyro to zero it.
            StartCoroutine(WaitThenZeroXSensGyro());
        }
        catch (Exception ex)
        {
            Debug.LogWarningFormat("[BikeController] Exception while loading XSens Gyro. The DLL is probably missing.\n{0}", ex.Message);
        }
        #else
        Debug.LogWarning("[BikeController] ANT and XSens are not available on non-Windows platforms.");
        #endif

        // Initialize and attach all the supplemental components needed by Bike Controller.

        UIOverlay.SetBikeController(this);
        this.uiOverlay = gameObject.AddComponent <UIOverlay>();

        UIDebugOverlay.SetBikeController(this);
        this.uiDebugOverlay = gameObject.AddComponent <UIDebugOverlay>();

        this.bikePhysics  = new BikePhysics(this);
        this.bikeSteering = new BikeSteering(this, this.steeringCurve);

        // Disable collisions between player character and the terrain.
        CharacterController characterController = this.GetComponent <CharacterController>();
        TerrainCollider     terrainCollider     = CollisionDisabler.GetTerrainColliderForActiveTerrain();
        (new CollisionDisabler(characterController, terrainCollider)).Start();
    }
    /// <summary>
    /// The is a standard Unity method to do some cleanup when the game ends.
    /// </summary>
    void OnApplicationQuit()
    {
        // Stop any XSensGyro instances.
        XSensGyro.StopAll();

        // Stop any AntStick instances.
        AntStick.StopAll();
    }