最近兩日遇到了這個問題,百思不得其解,目前還尚未解決,在此記錄一下,待時間充裕,再來研究探討。
問題描述
人物在檢測到跳躍事件後,給一個初始速度,根據重力加速度和時間差,計算出當前人物的速度爲 。在當前調用的時間內,位移爲。
檢測是否落地採用了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,最終導致懸空。
至於出現這個問題的原因,還尚未清楚。