昨天修改完近戰功能後就可以加入聯擊功能了!
我這裡使用 UE5.6 模板的 AM_ComboAttack 來製作,裡面使用 Sections 來分開三個不同的攻擊動畫。也是我第一次用這種方式來做 Combo,不然之前都是直接拿三個動畫檔案做 Combo,比較浪費儲存資源。
iThome30daysCharacter.h
protected:
virtual void BeginPlay() override;
void AttackMontageEnded(UAnimMontage* Montage, bool bInterrupted);
FOnMontageEnded OnAttackMontageEnded;
UFUNCTION()
void OnAttackNotifyBegin(FName NotifyName, const FBranchingPointNotifyPayload& BranchingPointPayload);
public:
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoAttack(UAnimMontage* AnimMontage, FName ComboNotify);
public:
UPROPERTY(Category="Character: State", EditAnywhere, BlueprintReadWrite)
bool bIsAttacking;
bool bCanQueCombo=false;
FName NComboCheckNotify=FName("ComboCheck");
UPROPERTY(Category="Character: Attack", VisibleAnywhere, BlueprintReadOnly)
int ComboCount=0;
UPROPERTY(Category="Character: Attack", EditAnywhere)
UAnimMontage* AttackAnimMontage;
TArray<FName> AttackSectionNames;
iThome30daysCharacter.cpp
AiThome30daysCharacter::AiThome30daysCharacter()
{
OnAttackMontageEnded.BindUObject(this, &AiThome30daysCharacter::AttackMontageEnded);
}
void AiThome30daysCharacter::BeginPlay()
{
Super::BeginPlay();
if (UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance())
{
AnimInstance->OnPlayMontageNotifyBegin.AddDynamic(this, &AiThome30daysCharacter::OnAttackNotifyBegin);
}
}
void AiThome30daysCharacter::DoAttack(UAnimMontage* AnimMontage, FName ComboNotify)
{
// 第一次攻擊
if (!bIsAttacking)
{
NComboCheckNotify = ComboNotify;
AttackSectionNames.Empty();
for (int i=0; i<AnimMontage->GetNumSections(); i++)
{
// 新增 Section 的名字 到 AttackSectionNames
AttackSectionNames.Add(AnimMontage->GetSectionName(i));
}
bIsAttacking = true;
bCanQueCombo = false;
ComboCount = 0;
if (UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance())
{
// 播放 Montage
AnimInstance->Montage_Play(AnimMontage);
// 設定 Montage 結束後呼叫的功能
AnimInstance->Montage_SetEndDelegate(OnAttackMontageEnded, AnimMontage);
}
}
if (bCanQueCombo)
{
++ComboCount;
if (ComboCount < AttackSectionNames.Num())
{
bCanQueCombo = false; // 防止亂切
if (UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance())
{
//GEngine->AddOnScreenDebugMessage(FCString::Atoi(TEXT("combo")), 2, FColor::Green, AttackSectionNames[ComboCount].ToString());
AnimInstance->Montage_JumpToSection(AttackSectionNames[ComboCount], AnimMontage);
}
}
}
}
void AiThome30daysCharacter::OnAttackNotifyBegin(FName NotifyName, const FBranchingPointNotifyPayload& BranchingPointPayload)
{
if (NotifyName == NComboCheckNotify)
{
bCanQueCombo = true;
}
}
void AiThome30daysCharacter::AttackMontageEnded(UAnimMontage* Montage, bool bInterrupted)
{
bIsAttacking = false;
bCanQueCombo = false;
ComboCount = 0;
//GEngine->AddOnScreenDebugMessage(FCString::Atoi(TEXT("attak11")), 1.0f, FColor::Yellow, TEXT("ComboEnded"));
}
在 Notifies
點 Add Track,然後在 右邊 Track > 右鍵 > Add Notify > Montage Notify
接著選擇 Notify 後 在 右方 Detail 介面寫上 Notify name
到這裡就完成了!
可以進行 Combo 囉,但你會看到 Combo 之間是一瞬間變換的,如果是風格化的遊戲可能還行,但其他的就看起來怪怪的,下次再來看能不能修正這個問題。