public void DoMove(float horL, float verL, float horR, float verR)
    {
        // Input axis as unit vector
        Vector3 movementRawL = new Vector3(horL, 0, verL);
        // Input right
        Vector3 movementRawR = new Vector3(horR, 0, verR);

        MovementLibrary.PlayerDropGravity(this);

        if (m_canWalk)
        {
            if (verL != 0 || horL != 0)
            {
                // Try and move the player
                MovementLibrary.MovePlayer(this, movementRawL, m_moveSpeed);
            }
        }

        if (m_cameraAnchor.transform.position != transform.position)
        {
            // Move camera to player position
            PositionCamera();
        }

        // Set player and camera rot
        OrientPlayerAndCamera(movementRawL, movementRawR);
    }
    IEnumerator PerformDash(Vector2 dashVectorNormalized, float timeToDash, float resetTime, float dashLength, CharacterSpace space = CharacterSpace.Camera)
    {
        // If instant (make appear instant, avoid division by 0)
        if (timeToDash == 0)
        {
            timeToDash = 0.001f;
        }

        // cache position at the start of this dash
        Vector3 startPos = transform.position;

        // toDash is the target dash based on the dash length and our dash vector (NORMALIZED)
        Vector3 toDash = (new Vector3(dashVectorNormalized.x, 0, dashVectorNormalized.y) * dashLength);

        // The stepping amount of dash
        Vector3 lastSubDashPos = new Vector3(0, 0, 0);


        // Disallow a dash to begin
        m_canDash = false;

        // Reset for safety
        m_dashResetTimer = 0;

        // Perform dash for the full time
        while (m_dashResetTimer < (timeToDash + resetTime))
        {
            if (m_dashResetTimer < timeToDash)
            {
                // Get the sub dash vector (timer based)
                Vector3 thisLerp = Vector3.Lerp(Vector3.zero, toDash, m_dashResetTimer / timeToDash);

                // Actually move the player
                MovementLibrary.MovePlayer(this, thisLerp - lastSubDashPos, space);

                // Set the last position to the current position
                lastSubDashPos = thisLerp;
            }

            m_dashResetTimer += Time.deltaTime;

            yield return(null);
        }

        // Allow for re-dashing
        m_canDash = true;

        // Drop out of dash (completed)
        yield return(null);
    }