// Update is called once per frame
    void Update()
    {
        if (playerPhysics.stopped)
        {
            targetSpeed   = 0;
            currentSpeedX = 0;
        }

        if (playerPhysics.grounded)
        {
            delta.y = 0;
        }

        if (upheld && Input.GetAxisRaw("Vertical") == 0)
        {
            upheld = false;
        }

        if (canControl && Input.GetButtonDown("Jump"))
        {
            if (!climbing && playerPhysics.grounded)
            {
                AudioManager.Instance.playSound(Sfx.JUMP, transform.position);
                delta.y = jumpHeight;
            }
            else if (climbing)
            {
                AudioManager.Instance.playSound(Sfx.JUMP, transform.position);
                upheld   = true;
                climbing = false;
                delta.y  = playerPhysics.atEdge() ? powerjumpHeight : jumpHeight;
                playerPhysics.climbing = false;
            }
        }

        if (canControl)
        {
            moveDirX = Input.GetAxisRaw("Horizontal");
            moveDirY = Input.GetAxisRaw("Vertical");
        }

        if (moveDirY > 0 && !climbing && playerPhysics.canGrab() && !upheld)
        {
            climbing      = true;
            currentSpeedX = 0;
            playerPhysics.Grab();
        }

        if (!climbing)
        {
            targetSpeed   = moveDirX * speed;
            currentSpeedX = IncrementTowards(currentSpeedX, targetSpeed, acceleration);

            delta.x  = currentSpeedX;
            delta.y -= gravity * Time.deltaTime;
        }
        else
        {
            targetSpeed   = moveDirY * climbspeed;
            currentSpeedY = IncrementTowards(currentSpeedY, targetSpeed, climbAcceleration);
            delta.x       = 0;
            delta.y       = currentSpeedY;
        }

        Animate();
        if (!freeze)
        {
            playerPhysics.Move(delta * Time.deltaTime, moveDirX);
        }
    }