Files
Lefteris Notas eeb1bf82c9 feat: Enhance interaction and inventory systems with new components and functionality
- Added BPC_UsableWorldObjectSystem for handling various interactable world objects with detailed manual implementation guide.
- Introduced BPC_ActiveItemSystem to manage quick slots and active item usage, including cycling and selection logic.
- Implemented BPC_DocumentArchiveSystem for managing collectible documents with read tracking and categorization.
- Developed BPC_JournalSystem for narrative entries with auto-adding features based on gameplay events.
- Created BPC_KeyItemSystem for key management with consumable and persistent key support.
- Enhanced BPC_FirearmSystem for ranged weapon mechanics, including hitscan and projectile firing.
- Updated BPC_MeleeSystem for melee combat with combo and blocking mechanics.
- Established BPC_ReloadSystem for managing weapon reloading processes, including partial reloads and state management.
2026-05-19 18:37:42 +03:00

245 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# BPC_MeleeSystem — Melee Weapon Component
## Blueprint Spec — UE 5.55.7
---
### Parent Class
`ActorComponent`
### Dependencies
- [`BPC_DamageReceptionSystem`](BPC_DamageReceptionSystem.md)
- [`BPC_CombatFeedbackComponent`](54_BPC_CombatFeedbackComponent.md)
- [`I_Damageable`](../01-core/03_I_InterfaceLibrary.md)
- [`DA_WeaponData`](../14-data-assets/)
- Owner Character Animation Blueprint
### Purpose
Melee weapon specialization. Handles swing detection, hitbox overlap checking during windup / active frames, and combo chain sequencing. Supports light attacks, heavy attacks, charge attacks, and block/parry.
### Variables
| Name | Type | Description |
|------|------|-------------|
| `ComboSection` | FName | Active montage section for combo |
| `ComboStep` | Int | Current combo step index |
| `bCanCombo` | Bool | True during window after hit or end of swing |
| `ComboWindowDuration` | Float | Seconds to chain next attack |
| `SwingMontage` | UAnimMontage | Full melee animation set |
| `HitDetectionCollision` | UCapsuleComponent | Overlap collision for hit detection |
| `bHitRegistered` | Bool | Prevents multi-hit on same swing |
| `HitActors` | Array<AActor> | Already hit this swing |
| `SwingPhase` | ESwingPhase | Windup / Active / Recovery / Idle |
| `ChargeDuration` | Float | Hold time for charged heavy attack |
| `bIsBlocking` | Bool | Currently blocking stance |
| `ParryWindow` | Float | Active parry frames in seconds |
| `bParryActive` | Bool | Within parry active window |
| `StaggerDuration` | Float | Hit reaction stun (self or target) |
### Enums
| Enum | Values | Description |
|------|--------|-------------|
| `ESwingPhase` | Idle, WindUp, Active, Recovery, ParryWindow | Attack animation phase |
| `EAttackType` | LightAttack, HeavyAttack, ChargeAttack, SprintAttack, ParryRiposte | Swing variant |
### Functions
| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `StartSwing` | AttackType: EAttackType | — | Play montage section, set SwingPhase |
| `OnSwingWindup` | — | — | Begin hit detection |
| `OnSwingActive` | — | — | Enable HitDetectionCollision overlap |
| `OnSwingHit` | HitResult: FHitResult | — | Single hit registration |
| `OnSwingRecovery` | — | — | Disable hit collision, check combo window |
| `OnSwingComplete` | — | — | Return to Idle |
| `StartBlock` | — | — | Play blocking animation |
| `EndBlock` | — | — | Release block stance |
| `ParryCheck` | IncomingAttack | Bool | If parry window active → counter |
| `GetComboStep` | — | Int | Return current combo index |
| `ResetCombo` | — | — | Clear combo step counter |
### Blueprint Flow
```
[Combo Chain Logic]
LightAttackInput →
If SwingPhase == Idle:
ComboStep = 0
StartSwing(LightAttack)
ElseIf SwingPhase == Active || SwingPhase == Recovery:
If bCanCombo && ComboStep < MaxComboLength:
ComboStep++
StartSwing(LightAttack) — next section of montage
[OnSwingActive — called by Animation Notify]
└─► HitDetectionCollision.SetCollisionEnabled(QueryOnly)
└─► On overlap → OnSwingHit
[OnSwingHit]
└─► If HitActor already in HitActors → return
└─► Add HitActor to HitActors
└─► If HitActor implements I_Damageable:
BPC_DamageReceptionSystem.ApplyMeleeDamage(
Damage = WeaponData.Damage * AttackTypeMultiplier,
HitActor,
HitLocation,
ImpulseDirection
)
└─► BPC_CombatFeedbackComponent.PlayHitFX(HitResult)
└─► ApplyStagger(HitActor)
[OnSwingRecovery — called by Animation Notify]
└─► HitDetectionCollision.SetCollisionEnabled(NoCollision)
└─► HitActors.Empty
└─► Set bCanCombo = true
└─► Start timer for ComboWindowDuration
└─► If no combo input received → OnSwingComplete
[OnSwingComplete]
└─► SwingPhase = Idle
└─► bCanCombo = false
└─► ComboStep = 0
[StartBlock]
└─► bIsBlocking = true
└─► Play block montage loop section
└─► Owner movement speed reduced
[ParryCheck]
└─► If bParryActive && incoming swing phase == Active:
Play parry riposte animation
Stagger incoming attacker
Return true
└─► Return false
```
### Communications With
| Target | Method | Why |
|--------|--------|-----|
| [`BPC_DamageReceptionSystem`](BPC_DamageReceptionSystem.md) | Get Component | Apply melee damage and stagger |
| [`BPC_CombatFeedbackComponent`](54_BPC_CombatFeedbackComponent.md) | Get Component | Swing whoosh, hit impact, block sparks |
| Owner Animation Blueprint | Direct | Query SwingPhase for animation state |
| Owner Character Movement | Direct | Reduce speed during block |
| Owner Character Input | Direct | Light / Heavy / Block input mapping |
| [`I_Damageable`](../01-core/03_I_InterfaceLibrary.md) | Interface | Damage application on hit actors |
### Reuse Notes
- Uses animation notifies for phase transitions (Notify_Windup, Notify_Active, Notify_Recovery, Notify_CanCombo, Notify_ParryWindow).
- Combo system uses montage section names "Combo_1", "Combo_2", etc.
- Hit collision is a simple box or capsule that exists only during Active phase.
- Block reduces incoming damage via DamageReception; parry reflects stagger.
- Renamed from `BP_MeleeWeapon` to `BPC_MeleeSystem` per Master naming convention.
- Cross-references updated: `BPC_DamageHandlerComponent``BPC_DamageReceptionSystem`.
---
## Manual Implementation Guide
### Class Setup
1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_MeleeSystem`
2. Attach to `BP_WeaponBase` subclass: `BP_MeleeWeapon`
3. Add `HitDetectionCollision` (Capsule or Box component) to weapon — disabled by default
### Variable Init (BeginPlay)
```
Event BeginPlay
├─ Set SwingPhase = Idle
├─ Set ComboStep = 0
├─ Set bCanCombo = false
├─ Set bIsBlocking = false
├─ Disable HitDetectionCollision (NoCollision)
├─ Get Owner Weapon → Read DA_WeaponData for: ComboWindowDuration, ChargeDuration, ParryWindow, StaggerDuration
└─ Get Owner → Find BPC_DamageReceptionSystem → Cache
```
### Function Implementations
#### `StartSwing(AttackType: EAttackType)` → `void`
```
[Function: StartSwing]
Step 1: Branch on SwingPhase != Idle AND SwingPhase != Recovery → Return (can't chain now)
Step 2: Set SwingPhase = WindUp
Step 3: Build montage section name:
If this is combo: "Combo_" + ComboStep
If AttackType == HeavyAttack: prefix "Heavy_"
If AttackType == ChargeAttack: "Charge_"
Step 4: Play Montage (SwingMontage, Section = built section name)
Step 5: Set bHitRegistered = false, Clear HitActors array
Step 6: Fire OnSwingStarted(AttackType, ComboStep)
```
**Nodes:** `Switch on EAttackType`, `Build String`, `Play Montage` (with Starting Section), `Clear Array`
#### `OnSwingActive()` → `void` *(Called by Animation Notify: "Notify_Active")*
```
Step 1: Set SwingPhase = Active
Step 2: HitDetectionCollision.SetCollisionEnabled(QueryOnly)
Step 3: Set bHitRegistered = false
```
#### `OnSwingHit(HitResult)` → `void` *(Called by HitDetectionCollision OnComponentBeginOverlap)*
```
Step 1: Get Hit Actor from Overlap → Cast to Actor
Step 2: ForEach HitActors → if match found → Return (already hit this actor this swing)
Step 3: Add HitActor to HitActors
Step 4: If HitActor implements I_Damageable:
Get BPC_DamageReceptionSystem → Call ApplyMeleeDamage:
BaseDamage = WeaponData.Damage
Multiplier: Light=1.0, Heavy=1.8, Charge=2.5, Sprint=1.5
HitLocation = HitResult.ImpactPoint
Apply impulse in swing direction
Step 5: Get BPC_CombatFeedbackComponent → Call PlayHitFX(HitResult)
Step 6: Apply Stagger to HitActor
```
#### `OnSwingRecovery()` → `void` *(Animation Notify: "Notify_Recovery")*
```
Step 1: Set SwingPhase = Recovery
Step 2: HitDetectionCollision.SetCollisionEnabled(NoCollision)
Step 3: Clear HitActors
Step 4: Set bCanCombo = true
Step 5: Start Timer (ComboWindowDuration) → On timer: if no combo received → OnSwingComplete()
```
#### `OnSwingComplete()` → `void`
```
Step 1: Set SwingPhase = Idle
Step 2: Set bCanCombo = false
Step 3: Set ComboStep = 0
Step 4: Fire OnSwingFinished
```
#### `StartBlock()` → `void`
```
Step 1: Set bIsBlocking = true
Step 2: Play block montage loop section
Step 3: Get Owner Character → Get CharacterMovement → Set MaxWalkSpeed *= 0.5
Step 4: Set ParryWindow timer: bParryActive = true for ParryWindow seconds
On timer end → bParryActive = false
```
#### `EndBlock()` → `void`
```
Step 1: Set bIsBlocking = false
Step 2: Stop block montage
Step 3: Restore MaxWalkSpeed
```
### Build Checklist
- [ ] Create BPC_MeleeSystem, add to BP_MeleeWeapon
- [ ] Add HitDetectionCollision component (Capsule/Box, NoCollision by default)
- [ ] Create SwingMontage with sections: Combo_1, Combo_2, Combo_3, Heavy_1, Charge_1
- [ ] Place Animation Notifies: Notify_Active, Notify_Recovery, Notify_CanCombo, Notify_ParryWindow
- [ ] Implement phase state machine: Idle→WindUp→Active→Recovery→(combo)→Idle
- [ ] Bind HitDetectionCollision.OnComponentBeginOverlap → OnSwingHit
- [ ] Implement combo system with bCanCombo window timer
- [ ] Implement block/parry with damage reduction and stagger reflection