Unity3d 人物跳躍後落地懸空問題

最近兩日遇到了這個問題,百思不得其解,目前還尚未解決,在此記錄一下,待時間充裕,再來研究探討。


問題描述

人物在檢測到跳躍事件後,給一個初始速度v0v_0,根據重力加速度gg和時間差tt,計算出當前人物的速度爲 v=v0gtv= v_0 -g * t。在當前調用的t\triangle t時間內,位移爲y=vt\triangle y= v*\triangle t
檢測是否落地採用了Physics.CapsuleCast函數,判斷人物是否與地面足夠近,然後重新設置人物的座標(根據hit.distance計算出的與地面的距離)。

但是,不知爲何人物在落地時,總會高出地面0.25,後續跳躍就總是以此爲平面了。
跳躍之後身體懸空
檢測碰撞的代碼如下:

// 判斷是否落地
void GroundCheck()
{
    // Make sure that the ground check distance while already in air is very small, to prevent suddenly snapping to ground
    float groundCheckDistance = -m_JumpSpeed * Time.deltaTime;       
    float slopeLimit = 0.1f;        //  可落地地形角度

    // reset values before the ground check
    Vector3 m_GroundNormal = Vector3.up;
    Debug.Log(check_height);

    if (m_JumpSpeed <= 0)
    {
        // if we're grounded, collect info about the ground normal with a downward capsule cast representing our character capsule
        if (Physics.CapsuleCast(GetCapsuleBottomPoint(), GetCapsuleTopPoint(), m_CharaContr.radius, Vector3.down, out RaycastHit hit, 0.1f))
        {
            // storing the upward direction for the surface found
            m_GroundNormal = hit.normal;

            // Only consider this a valid ground hit if the ground normal goes in the same direction as the character up
            // and if the slope angle is lower than the character controller's limit
            if (Vector3.Dot(hit.normal, transform.up) > 0f &&
                Vector3.Angle(transform.up, m_GroundNormal) <= slopeLimit)
            {
                isJumping = false;
                m_Animator.SetBool("isJumping", isJumping);
               // handle snapping to the ground
                if (hit.distance > m_CharaContr.skinWidth)
                {
                    m_CharaContr.transform.Translate(Vector3.down * hit.distance);
                }
            }
        }
    }
}

Vector3 GetCapsuleBottomPoint()
{
    return m_CharaContr.transform.position + m_CharaContr.center + Vector3.up * -m_CharaContr.height * 0.5F;
}

Vector3 GetCapsuleTopPoint()
{
    return GetCapsuleBottomPoint() + Vector3.up * m_CharaContr.height;
}

通過一番排查,問題主要出在Physics.CapsuleCast部分,它在距離地面0.25f+hit.distance的時候就認爲掃描到了碰撞體。同時hit.distance總要小0.25,最終導致懸空。

至於出現這個問題的原因,還尚未清楚。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章