private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.tag.Equals("Ground") || collision.gameObject.tag.Equals("Untagged"))
        {
            onGround      = true;
            rb.useGravity = true;

            jumpEnvelope = JumpEnvelope_t.jmpSUSTAIN;
        }
    }
    public void PlayerJump(float jumpheight)
    {
        jumpTimeStart = Time.time;
        jumpStartY    = transform.position.y;
        jumpApexY     = jumpStartY + jumpheight;
        jumpEnvelope  = JumpEnvelope_t.jmpATTACK;
        rb.useGravity = false;

        onGround = false;
        AudioSource.PlayClipAtPoint(audioJump, this.transform.position);
    }
    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.tag.Equals("Ground") || collision.gameObject.tag.Equals("Untagged"))
        {
            if (jumpEnvelope != JumpEnvelope_t.jmpATTACK)
            {
                jumpEnvelope  = JumpEnvelope_t.jmpLEDGEDROP;
                jumpFallSpeed = 0;
            }

            rb.useGravity = false;
            //onGround = false;
            this.transform.parent = null;
        }

        //check if not touching pullable object when not pulling
        if (collision.gameObject.tag.Equals("PullableObject"))
        {
            if (!grabbing)
            {
                nearPullObject = null;
            }
        }
    }
    void FixedUpdate()
    {
        PlayerMove();
        PlayerRotate();//set  player rotation

        switch (jumpEnvelope)
        {
        case JumpEnvelope_t.jmpATTACK:
            float ofAthirdSecond = (Time.time - jumpTimeStart) * 3;
            float elapsedTime    = Mathf.Min(Mathf.Log(ofAthirdSecond * 9 + 1, 10), 1.0f);
            if (elapsedTime == 1.0f)
            {
                jumpEnvelope = JumpEnvelope_t.jmpSUSTAIN;

                jumpFallSpeed = 0.0f;
            }

            Vector3 startPos = transform.position;
            startPos.y = jumpStartY;

            Vector3 endPos = transform.position;
            endPos.y = jumpApexY;

            transform.position = Vector3.Lerp(startPos, endPos, elapsedTime);
            break;

        case JumpEnvelope_t.jmpFALL:
            if (onGround)
            {
                break;
            }

            jumpFallSpeed += Time.deltaTime * jumpFallAcceleration / 2;
            goto case JumpEnvelope_t.jmpSUSTAIN;

        case JumpEnvelope_t.jmpSUSTAIN:
            if (onGround)
            {
                break;
            }
            else
            {
                jumpFallSpeed += Time.deltaTime * jumpFallAcceleration / 2;
            }

            // stop half speed drop
            if (!Input.GetButton("Jump"))
            {
                jumpEnvelope = JumpEnvelope_t.jmpFALL;
            }

            jumpFallSpeed       = Mathf.Min(jumpFallSpeed, playerSpeed * 1.5f);
            transform.position -= new Vector3(0, jumpFallSpeed, 0);
            break;

        case JumpEnvelope_t.jmpLEDGEDROP:
            jumpFallSpeed      += Time.deltaTime * jumpFallAcceleration / 2;
            jumpFallSpeed       = Mathf.Min(jumpFallSpeed, playerSpeed * 1.5f);
            transform.position -= new Vector3(0, jumpFallSpeed, 0);
            break;
        }
    }