/// <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();
    }
    void FixedUpdate()
    {
        // Steering Update
        this.bikeSteering.DoOnFixedUpdate();
        this.Heading += this.bikeSteering.BikeHeadingChange;
        this.bikeAnimator.handlesAngle = this.bikeSteering.HandlesAnglePostProcessed;

        // Physics Update
        if (!this.bikeData.IgnoreKickrVelocity)
        {
            this.bikePhysics.KickrVelocity = this.bikeData.BikeSpeed;
        }
        this.bikePhysics.DoOnFixedUpdate();

        if (this.bikeData.UsingAntKickr)
        {
            AntStickBridge.SendResistance(this.bikePhysics.KickrResistance);
        }
        transform.position = this.bikePhysics.FallPosition;
        transform.rotation = Quaternion.LookRotation(this.bikePhysics.MovementDirection);

        // Perform Movement
        Vector3        desiredMove = this.bikePhysics.VelocityVector * Time.deltaTime;
        CollisionFlags flags       = characterController.collisionFlags;

        if (flags == CollisionFlags.Sides)
        {           // COLLISION
            RaycastHit hitInfo;
            Physics.SphereCast(transform.position, characterController.radius, Vector3.forward, out hitInfo, characterController.height / 2f);
            desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized *bikePhysics.Velocity *Time.deltaTime;

            float moveVelocity = desiredMove.magnitude;
            float acceleration = (bikePhysics.Velocity - moveVelocity) / Time.deltaTime;
            bikePhysics.ApplyCollisionForce(acceleration);

            this._distanceTravelled += (moveVelocity * Time.deltaTime);
        }
        else
        {   // NO COLLISION
            this._distanceTravelled += (bikePhysics.Velocity * Time.deltaTime);

            if (bikePhysics.Velocity >= 0f && bikePhysics.Velocity <= 200f)
            {
                this.bikeAnimator.wheelRPM = bikePhysics.Velocity / this.bikeData.BikeRPMToLinearVelocityFactor;
                this.bikeAnimator.pedalRPM = this.bikeAnimator.wheelRPM / 2f;
            }
        }
        characterController.Move(desiredMove);
    }