今のところ武器を装備しても攻撃アニメーションは素手の攻撃用アニメーションのままなので、新たに武器装備時の攻撃アニメーションを用意する必要があります。今回の武器は剣なので、剣装備時の攻撃アニメーションをいくつかMixamoからダウンロードしてきます。
アニメモンタージュにアニメーションを追加する
前回作成した攻撃用のアニメモンタージュに剣装備時の攻撃アニメーションを追加します。モンタージュにアニメーションを追加する方法はこの記事で詳しく説明されているのでここでは割愛します。今回新たに4つの剣攻撃アニメーションを追加したので、前回の9個のアニメーションと合わせた計13個のアニメーションがモンタージュに追加されたことになります。
注意が必要なのは、新たにアニメーションを追加した場合、必ずモンタージュセクションの赤いクリアボタンを押して、アニメーションを連続再生から個別再生に変更することです。それと、セクション毎にAttackEndの通知を付けることも必須です。この通知の位置を変えることでアニメーションの微調整を行うことでできます。
C++で攻撃パターンを切り替える
MyCharacter.cppのattack関数を書き換えて武器装備時と未装備時の攻撃アニメーションを切り替えます。
考え方としては、武器を未装備時をnullptrでifチェックを入れて、値がtrueの場合は素手用の攻撃モンタージュを使用し、falseの場合は剣装備時の攻撃モンタージュを使用するようにします。
void AMyCharacter::Attack() { bAttacking = true; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && AttackMontage) { if (EquippedWeapon == nullptr) { int32 Section = FMath::RandRange(0, 8); switch (Section) { case 0: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack1"), AttackMontage); break; case 1: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack2"), AttackMontage); break; case 2: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack3"), AttackMontage); break; case 3: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack4"), AttackMontage); break; case 4: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack5"), AttackMontage); break; case 5: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack6"), AttackMontage); break; case 6: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack7"), AttackMontage); break; case 7: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack8"), AttackMontage); break; case 8: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack9"), AttackMontage); break; default: ; } } else { int32 Section1 = FMath::RandRange(0, 3); switch (Section1) { case 0: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack10"), AttackMontage); break; case 1: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack11"), AttackMontage); break; case 2: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack12"), AttackMontage); break; case 3: AnimInstance->Montage_Play(AttackMontage, 2.5); AnimInstance->Montage_JumpToSection(FName("attack13"), AttackMontage); break; default: ; } } } }
このままだと武器を投げ捨てて素手に戻った後も剣装備時の攻撃アニメーションが再生されてしまうので、DropWeapon関数を以下のように書き換える必要があります。
void AMyCharacter::DropWeapon() { if (EquippedWeapon->GetWeaponState()==EWeaponState::EWS_Equipped) { FDetachmentTransformRules DetachmentTransformRules(EDetachmentRule::KeepWorld, true); EquippedWeapon->GetItemMesh()->DetachFromComponent(DetachmentTransformRules); EquippedWeapon->SetWeaponState(EWeaponState::EWS_Falling); EquippedWeapon->ThrowWeapon(); EquippedWeapon = nullptr; } }
最後にEquippedWeapon = nullptrを加えることで、武器を投げ捨てた後はEquippedWeaponはなし状態になります。これがないと、武器を捨てた後も武器を装備した状態になってしまうので武器を捨てた後も剣装備時のアニメーションが再生されてしまいます。
武器投げ捨て関連のバグ修正
今のままだとゲーム開始時にYボタンを押して武器を投げ捨てようとするとゲームがクラッシュしてしまいます。これは武器を投げ捨てようとしても武器がないためです。なので、武器を未装備状態の時はボタンを押しても何もしないようにifチェックを入れる必要があります。
void AMyCharacter::GPYPressed() { if (EquippedWeapon == nullptr) return; DropWeapon(); }
これでゲーム開始時にYボタンを押してもゲームはクラッシュしなくなります。
コメント