void Start()
    {
        m_Animator2D   = GetComponent <Animator2D>();
        m_Controller2D = GetComponent <Controller2D_SL>();

        m_v3DefaultScale = transform.localScale;

        m_fGravity      = -(2.0f * m_fJumpHeight) / (m_fTimeToJumpApex * m_fTimeToJumpApex);
        m_fJumpVelocity = Mathf.Abs(m_fGravity) * m_fTimeToJumpApex;
        print("Gravity: " + m_fGravity + "|| JumpVel: " + m_fJumpVelocity);

        //Give the character states access this script

        m_StationaryState = new StationaryCharacterState();
        m_RunState        = new RunCharacterState();
        m_JumpUpState     = new JumpUpCharacterState();
        m_FallDownState   = new FallDownCharacterState();

        m_StationaryState.PlayerControllerScript = this;
        m_RunState.PlayerControllerScript        = this;
        m_JumpUpState.PlayerControllerScript     = this;
        m_FallDownState.PlayerControllerScript   = this;

        EnterCharacterState(PlayerCharacterState.ECharacterState.Stationary);
        m_eWeaponState                 = PlayerCharacterState.ECharacterWeaponState.BlasterInactive;
        m_tmWeaponStateTimer           = new System.Timers.Timer(333);
        m_tmWeaponStateTimer.AutoReset = false;
        m_tmWeaponStateTimer.Elapsed  +=
            (object sender, System.Timers.ElapsedEventArgs e) =>
        {
            m_bWeaponStateDirty = true;
            m_eWeaponState      = PlayerCharacterState.ECharacterWeaponState.BlasterInactive;
        };
    }
    void Update()
    {
        //Quick reset for our character's position
        if (Input.GetKeyUp(KeyCode.F))
        {
            transform.position = m_v3QuickTeleportPosition;
            m_v3Velocity       = Vector3.zero;
        }

        if (Input.GetKeyUp(KeyCode.Z))
        {
            m_bWeaponStateDirty = (m_eWeaponState != PlayerCharacterState.ECharacterWeaponState.BlasterActive);
            m_eWeaponState      = PlayerCharacterState.ECharacterWeaponState.BlasterActive;
            m_tmWeaponStateTimer.Stop();
            m_tmWeaponStateTimer.Start();
        }

        if (m_bWeaponStateDirty)
        {
            m_CharacterState.CorrectWeaponState();
            CorrectWeaponStateAnimation();
            m_bWeaponStateDirty = false;
        }

        if (m_Controller2D.m_sCollisionData.m_bAbove ||
            m_Controller2D.m_sCollisionData.m_bBelow)
        {
            m_v3Velocity.y = 0;
        }

        m_CharacterState.Update();
        m_CharacterState.HandleInput();

        float moveHoriz = Input.GetAxisRaw("Horizontal");
        float moveVert  = Input.GetAxisRaw("Vertical");

        m_v2InputMovement = new Vector2(moveHoriz, moveVert);

        //apply player input to our horizontal velocity
        //we're using a smoothing function to make direction change not so abrupt
        float fTargetVelocityX = m_v2InputMovement.x * m_fMovementSpeed;

        m_v3Velocity.x = Mathf.SmoothDamp(m_v3Velocity.x, fTargetVelocityX, ref m_fVelocityXSmoothing,
                                          m_Controller2D.m_sCollisionData.m_bBelow ? m_fAccelerationTimeGrounded : m_fAccelerationTimeAirborn);

        //apply gravity to our vertical velocity
        m_v3Velocity.y += m_fGravity * Time.deltaTime;
        m_Controller2D.Move(m_v3Velocity * Time.deltaTime);
    }