承上一篇內容,我們再繼續完善我們的跳躍功能。
首先,我們現在的跳躍功能是只有自動在跳,沒有被玩家控制,所以我們要把判定跳躍的條件增加一條是玩家按下跳躍鍵後:
if (Physics2D.OverlapBox(groundCheckPoint.transform.position, new Vector2(0.1f, 0.1f), 0, LayerMask.GetMask("Ground")))
{
if(lastJumpTime > 30 && Input.GetButton("Jump"))
{
// 這段之後會變成 CharacterJump()
rb.velocity = new Vector2(rb.velocity.x, 0);
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
lastJumpTime = 0;
}
}
接著,我們可以製作之前提到的 Coyote Time,透過建立全域變數 bool isJumping 以及 lastGroundedTime,去追蹤玩家是在有沒有起跳的狀態下離開地面,並讓玩家在沒有離開按下跳躍鍵而離開了地面的短時間內一樣可以觸發跳躍:
private bool isJumping = false;
private int lastGroundedTime = 0;
// 觸地判定
if (Physics2D.OverlapBox(groundCheckPoint.transform.position, new Vector2(0.1f, 0.1f), 0, LayerMask.GetMask("Ground")))
{
// 重置觸地時間
lastGroundedTime = 0;
// 如觸地時沒按跳躍鍵,重置跳躍狀態
if (isJumping && !Input.GetButton("Jump"))
{
isJumping = false;
}
// 正常跳躍
if (lastJumpTime > 30 && Input.GetButton("Jump"))
{
CharacterJump();
// 把這個也加進 CharacterJump() 裹
isJumping = true;
}
}
// Coyote Time 跳躍
else if (lastGroundedTime < 10 && !isJumping && Input.GetButton("Jump"))
{
CharacterJump();
// 把這個也加進 CharacterJump() 裹
isJumping = true;
}
記得在 FixedUpdate() 最後補上:
lastGroundedTime++;
再來我們會製作 Jump cut,即跳躍到中間鬆開跳躍鍵時會中止上升的慣性,簡單的幾句其實已經可以做到這個效果,在跳躍的中途偵測到按鍵被放開時,確認角色沒有在下降時重置上下速率即可:
// Jump Cut
if(isJumping && Input.GetButtonUp("Jump"))
// 不是在下降
if(rb.velocity.y > 0)
rb.velocity = new Vector2(rb.velocity.x, 0);
然後 Input.GetButtonUp() 以及 Input.GetButtonDown() 這兩個功能有時間都會剛好沒有成功偵測到玩家按下或者放開按鍵那的那一刻,所以我們可以建立一個 bool 去追蹤玩家的輸入:
private bool isJumpBtnReleased = false;
// Jump Cut
if(isJumping && !Input.GetButton("Jump") && !isJumpBtnReleased)
{
// 不是在下降
if(rb.velocity.y > 0)
{
rb.velocity = new Vector2(rb.velocity.x, 0);
isJumpBtnReleased = true;
}
}