diff --git a/Content/Assets/Animations/Equip_Rifle_Standing.uasset b/Content/Assets/Animations/Equip_Rifle_Standing.uasset index 732066f..c017fd3 100644 Binary files a/Content/Assets/Animations/Equip_Rifle_Standing.uasset and b/Content/Assets/Animations/Equip_Rifle_Standing.uasset differ diff --git a/Content/Assets/Animations/SwapWeapons.uasset b/Content/Assets/Animations/SwapWeapons.uasset new file mode 100644 index 0000000..5da8b8d Binary files /dev/null and b/Content/Assets/Animations/SwapWeapons.uasset differ diff --git a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset index f49ef55..3b91ce3 100644 Binary files a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset and b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset differ diff --git a/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset b/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset index fd821e2..181091a 100644 Binary files a/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset and b/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset differ diff --git a/Content/Blueprints/Character/Animation/Swap.uasset b/Content/Blueprints/Character/Animation/Swap.uasset new file mode 100644 index 0000000..2b42c82 Binary files /dev/null and b/Content/Blueprints/Character/Animation/Swap.uasset differ diff --git a/Content/Blueprints/Character/BP_BlasterCharacter.uasset b/Content/Blueprints/Character/BP_BlasterCharacter.uasset index c8f92be..8005537 100644 Binary files a/Content/Blueprints/Character/BP_BlasterCharacter.uasset and b/Content/Blueprints/Character/BP_BlasterCharacter.uasset differ diff --git a/Source/Blaster/Character/BlasterAnimInstance.cpp b/Source/Blaster/Character/BlasterAnimInstance.cpp index 4425da8..19aa63d 100644 --- a/Source/Blaster/Character/BlasterAnimInstance.cpp +++ b/Source/Blaster/Character/BlasterAnimInstance.cpp @@ -74,7 +74,11 @@ void UBlasterAnimInstance::NativeUpdateAnimation(float DeltaTime) } bUseFABRIK = BlasterCharacter->GetCombatState() == ECombatState::ECS_Unoccupied; - if (BlasterCharacter->IsLocallyControlled() && BlasterCharacter->GetCombatState() != ECombatState::ECS_ThrowingGrenade) + bool bFABRIKOverride = BlasterCharacter->IsLocallyControlled() && + BlasterCharacter->GetCombatState() != ECombatState::ECS_ThrowingGrenade && + BlasterCharacter->bFinishedSwapping; + + if (bFABRIKOverride) { bUseFABRIK = !BlasterCharacter->IsLocallyReloading(); } diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index 9c48be9..2a4802a 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -434,6 +434,15 @@ void ABlasterCharacter::PlayThrowGrenadeMontage() } } +void ABlasterCharacter::PlaySwapMontage() +{ + UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); + if (AnimInstance && SwapMontage) + { + AnimInstance->Montage_Play(SwapMontage); + } +} + void ABlasterCharacter::PlayHitReactMontage() { if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; @@ -524,7 +533,18 @@ void ABlasterCharacter::EquipButtonPressed() if (bDisableGameplay) return; if (Combat) { - ServerEquipButtonPressed(); + if (Combat->CombatState == ECombatState::ECS_Unoccupied) ServerEquipButtonPressed(); + bool bSwap = Combat->ShouldSwapWeapons() && + !HasAuthority() && + Combat->CombatState == ECombatState::ECS_Unoccupied && + OverlappingWeapon == nullptr; + + if (bSwap) + { + PlaySwapMontage(); + Combat->CombatState = ECombatState::ECS_SwappingWeapons; + bFinishedSwapping = false; + } } } diff --git a/Source/Blaster/Character/BlasterCharacter.h b/Source/Blaster/Character/BlasterCharacter.h index f9424d4..a3dc13b 100644 --- a/Source/Blaster/Character/BlasterCharacter.h +++ b/Source/Blaster/Character/BlasterCharacter.h @@ -25,10 +25,13 @@ public: virtual void OnRep_ReplicatedMovement() override; virtual void Destroyed() override; void RotateInPlace(float DeltaTime); + + // Play Montages void PlayFireMontage(bool bAiming); void PlayReloadMontage(); void PlayEliminatedMontage(); void PlayThrowGrenadeMontage(); + void PlaySwapMontage(); void Eliminated(); @@ -48,7 +51,8 @@ public: void SpawnDefaultWeapon(); UPROPERTY() TMap HitCollisionBoxes; - + + bool bFinishedSwapping = false; protected: virtual void BeginPlay() override; @@ -191,6 +195,9 @@ private: UPROPERTY(EditAnywhere, Category = Combat) class UAnimMontage* ThrowGrenadeMontage; + UPROPERTY(EditAnywhere, Category = Combat) + class UAnimMontage* SwapMontage; + void HideCameraIfCharacterClose(); UPROPERTY(EditAnywhere) diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index b205257..8637b96 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -241,20 +241,13 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) void UCombatComponent::SwapWeapons() { - if (CombatState != ECombatState::ECS_Unoccupied) return; - - AWeapon* TempWeapon = PrimaryWeapon; - PrimaryWeapon = SecondaryWeapon; - SecondaryWeapon = TempWeapon; - - PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(PrimaryWeapon); - PrimaryWeapon->SetHUDAmmo(); - UpdateCarriedAmmo(); - PlayEquipWeaponSound(PrimaryWeapon); + if (CombatState != ECombatState::ECS_Unoccupied || Character == nullptr || !Character->HasAuthority()) return; - SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); - AttachActorToBackpack(SecondaryWeapon); + Character->PlaySwapMontage(); + CombatState = ECombatState::ECS_SwappingWeapons; + Character->bFinishedSwapping = false; + + if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(false); } bool UCombatComponent::ShouldSwapWeapons() @@ -421,6 +414,32 @@ void UCombatComponent::FinishedReloading() } } +void UCombatComponent::FinishedSwap() +{ + if (Character && Character->HasAuthority()) + { + CombatState = ECombatState::ECS_Unoccupied; + } + if (Character) Character->bFinishedSwapping = true; + if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(true); +} + +void UCombatComponent::FinishedSwapAttachWeapons() +{ + AWeapon* TempWeapon = PrimaryWeapon; + PrimaryWeapon = SecondaryWeapon; + SecondaryWeapon = TempWeapon; + + PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(PrimaryWeapon); + PrimaryWeapon->SetHUDAmmo(); + UpdateCarriedAmmo(); + PlayEquipWeaponSound(PrimaryWeapon); + + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); + AttachActorToBackpack(SecondaryWeapon); +} + void UCombatComponent::DropWeapons() { if (PrimaryWeapon) PrimaryWeapon->Dropped(); @@ -535,6 +554,12 @@ void UCombatComponent::OnRep_CombatState() ShowAttachedGrenade(true); } break; + case ECombatState::ECS_SwappingWeapons: + if (Character && !Character->IsLocallyControlled()) + { + Character->PlaySwapMontage(); + } + break; } } @@ -790,9 +815,9 @@ bool UCombatComponent::CanFire() { if (PrimaryWeapon == nullptr) return false; if (PrimaryWeapon->IsEmpty()) return false; - if (bLocallyReloading) return false; if (!bCanFire) return false; if (CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true; + if (bLocallyReloading) return false; return CombatState == ECombatState::ECS_Unoccupied; } diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index 2239f3c..8073d13 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -28,6 +28,12 @@ public: void DropWeapons(); UFUNCTION(BlueprintCallable) void FinishedReloading(); + + UFUNCTION(BlueprintCallable) + void FinishedSwap(); + + UFUNCTION(BlueprintCallable) + void FinishedSwapAttachWeapons(); void FireButtonPressed(bool bPressed); diff --git a/Source/Blaster/Types/CombatState.h b/Source/Blaster/Types/CombatState.h index 5c5522a..07b9fbe 100644 --- a/Source/Blaster/Types/CombatState.h +++ b/Source/Blaster/Types/CombatState.h @@ -6,6 +6,7 @@ enum class ECombatState : uint8 ECS_Unoccupied UMETA(DisplayName = "Unoccupied"), ECS_Reloading UMETA(DisplayName = "Reloading"), ECS_ThrowingGrenade UMETA(DisplayName = "Throwing Grenade"), + ECS_SwappingWeapons UMETA(DisplayName = "Swapping Weapons"), ECS_MAX UMETA(DisplayName = "DefaultMAX") }; diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index adff03e..59da0d7 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -240,7 +240,6 @@ void AWeapon::OnEquippedSecondary() WeaponMesh->SetEnableGravity(true); WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); } - EnableCustomDepth(true); if (WeaponMesh) { WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_TAN);