我想要做像 Elden Ring 一樣,可以讓角色快速移動、迴避攻擊的功能。
今天我們會透過 C++ 和 Blueprint 組合,新增一個簡單的 Dodge 機制。
在 iThome30daysCharacter.h
裡新增 Dodge 相關的
變數 :
public:
UPROPERTY(Category="Character: State", EditAnywhere, BlueprintReadWrite)
bool bIsSprinting;
UPROPERTY(Category="Character: State", EditAnywhere, BlueprintReadWrite)
bool bIsDodging;
UPROPERTY(Category="Character Movement: Dodge", EditAnywhere)
float DodgeDuration;
UPROPERTY(Category="Character Movement: Dodge", EditAnywhere)
float LastShiftTime;
UPROPERTY(Category="Character Movement: Dodge", EditAnywhere)
float DoubleTapThreshold; // 0.25秒內按兩次才算
protected:
FTimerHandle DodgeTimerHandle;
UPROPERTY(EditAnywhere, BlueprintReadWrite) 讓變數能夠在藍圖裡被編輯。
與 函式 :
public:
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoDodge();
protected:
void StartDodge();
void EndDodge();
UFUNCTION(BlueprintCallable) 讓功能能夠在藍圖裡使用。
在 iThome30daysCharacter.cpp
加上:
Dodge判斷
void AiThome30daysCharacter::DoDodge()
{
float CurrentTime = GetWorld()->GetTimeSeconds();
if (LastShiftTime > 0 && (CurrentTime - LastShiftTime) <= DoubleTapThreshold)
{
StartDodge(); // 觸發 Dodge
LastShiftTime = -1.0f; // reset
}
else
{
LastShiftTime = CurrentTime;
}
}
因為我想做 Elden Ring 那樣雙擊 Shift 來執行閃避,所以這裡加了雙擊判定
開始 / 停止閃避
void AiThome30daysCharacter::StartDodge()
{
if (bIsDodging) return;
bIsDodging = true;
GetWorldTimerManager().SetTimer(DodgeTimerHandle, this, &AiThome30daysCharacter::EndDodge, DodgeDuration, false);
}
void AiThome30daysCharacter::EndDodge()
{
bIsDodging = false;
}
因為之後要用 **Root Motion Animation** 來做閃避動畫,所以這裡沒有加任何角色動量修改。
接下來切換到 Blueprint (ThirdPersonCharacter Event Graph),將 Shift 綁定到 DoDodge():
明天我們會開始研究 動畫系統,讓 閃避動作能搭配正確的動畫播放。