Files
UE5-Modular-Game-Framework/docs/blueprints/03-interaction/22_BPC_PhysicsDragSystem.md
Lefteris Notas fef25a3363 Enhance documentation with Manual Implementation Guides and Build Checklists
- Updated `CONTEXT.md` to reference the new Manual Implementation Guide and Build Checklist in blueprint spec files.
- Added a detailed Manual Implementation Guide to `01_GI_GameTagRegistry.md`, including class setup, variable initialization, function implementations, and a build checklist.
- Introduced a Manual Implementation Guide section in `22_BPC_PhysicsDragSystem.md` with step-by-step instructions for setup and function logic.
- Expanded `28_BPC_ConsumableSystem.md` with a comprehensive Manual Implementation Guide detailing class setup, variable initialization, function implementations, and networking.
- Enhanced `69_BP_WeaponBase.md` with a Manual Implementation Guide covering class setup, variable defaults, function implementations, and networking.
- Added a Manual Implementation Guide to `84_AI_BaseAgentController.md`, outlining class setup, variable initialization, function implementations, and networking.
- Updated `TEMPLATE.md` to version 2.0, incorporating the Manual Implementation Guide and Build Checklist for human implementers.
- Revised `INDEX.md` to reflect the new purpose and content of blueprint specifications, emphasizing the inclusion of the Manual Implementation Guide.
2026-05-19 17:51:03 +03:00

232 lines
8.6 KiB
Markdown
Raw 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_PhysicsDragSystem — Physics Drag System
**Parent Class:** `ActorComponent`
**Category:** Interaction
**Target UE Version:** 5.55.7
**Build Phase:** 2 — Interaction
---
## 1. Overview
`BPC_PhysicsDragSystem` allows the player to grab and physically drag rigid-body objects in the world. Supports grab-at-distance, hold-to-grab with physics constraints, object rotation, and throw mechanics. Integrates with the interaction detector for grab targeting.
---
## 2. Enums
### `E_DragMode`
| Value | Description |
|-------|-------------|
| `PhysicsConstraint` | Attaches object via physics constraint to player hand |
| `Kinematic` | Sets object to kinematic and parents to hand |
| `Magnetic` | Objects smoothly lerp toward grab point |
---
## 3. Variables
| Name | Type | Description |
|------|------|-------------|
| `DragMode` | `E_DragMode` | Current drag physics mode |
| `GrabbedObject` | `AActor*` | Currently held actor |
| `ConstraintComp` | `UPhysicsConstraintComponent*` | Physics constraint for held object |
| `GrabDistance` | `float` | Max distance to grab (cm) |
| `HoldDistance` | `float` | Distance object is held from camera |
| `ThrowForce` | `float` | Impulse applied on release |
| `RotationSpeed` | `float` | Degrees/sec for object rotation input |
| `bCanThrow` | `bool` | Object can be thrown on release |
| `bIsGrabbing` | `bool` | Currently holding an object |
---
## 4. Functions
| Function | Description |
|----------|-------------|
| `GrabObject` | Attempts to grab targeted physics object. Returns bool. |
| `ReleaseObject` | Releases held object, applies throw force if bCanThrow. |
| `RotateObject` | Rotates held object by input axis values |
| `SetHoldDistance` | Adjusts distance of held object from camera |
| `GetGrabbedObject` | Returns currently held actor (or null) |
| `IsGrabbing` | Returns `bIsGrabbing` |
---
## 5. Event Dispatchers
| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnObjectGrabbed` | `AActor* GrabbedObject` | Object successfully grabbed |
| `OnObjectReleased` | `AActor* ReleasedObject`, `bool bWasThrown` | Object released |
| `OnGrabFailed` | `FText FailReason` | Grab attempt failed |
---
## 6. Blueprint Flow
```
GrabObject:
→ Get targeted object from InteractionDetector
→ Check if object has physics simulation enabled
→ If DragMode == PhysicsConstraint:
→ Create physics constraint between hand socket and object
→ Set constraint limits (linear + angular)
→ If DragMode == Kinematic:
→ Set object simulated physics to false
→ Attach to hand socket
→ Set bIsGrabbing = true
→ Broadcast OnObjectGrabbed
ReleaseObject:
→ If bCanThrow → Apply forward impulse * ThrowForce
→ Destroy constraint / detach
→ Re-enable physics on object
→ Set bIsGrabbing = false
→ Broadcast OnObjectReleased
```
---
## 7. Dependencies & Communication
| System | Relationship |
|--------|--------------|
| `BPC_InteractionDetector` | Provides grab target via focus |
| `BPC_CameraStateLayer` | Camera direction for throw vector |
| `BPC_MovementStateSystem` | Speed modifier while carrying objects |
---
## 8. Reuse Notes
- Physics drag uses UE5 physics constraint system for realistic object handling
- Objects must have `Simulate Physics = true` and `Mass` configured
---
## 9. Manual Implementation Guide
### 9.1 Class Setup
1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_PhysicsDragSystem`
2. Save to: `Content/Framework/Interaction/`
3. Add to your Player Character.
### 9.2 Variable Initialization (BeginPlay)
```
Event BeginPlay
├─ Set bIsGrabbing = false
├─ Set GrabbedObject = None
├─ Get Owner → Get Component by Class (BPC_InteractionDetector) → Store reference
└─ Get Owner → Get PlayerCameraManager → Store for throw direction
```
### 9.3 Function Implementations
#### `GrabObject(TargetActor: Actor)` → `Boolean`
**Node-by-Node Logic:**
```
[Function: GrabObject]
Step 1: Branch on bIsGrabbing → If true, ReleaseObject first
Step 2: Branch on IsValid(TargetActor) → If not, return false
Step 3: Get TargetActor → Get Component by Class (StaticMeshComponent)
└─ Check: Is Simulate Physics Enabled? → If not, Fire OnGrabFailed("No physics"), return false
Step 4: Check mass: StaticMeshComponent.GetMass() → If > MaxGrabMass, fail
Step 5: Switch on DragMode:
Case PhysicsConstraint:
- Create Physics Constraint component (spawn dynamically)
- ConstraintComp.SetConstrainedComponents(StaticMeshComponent, None, PlayerHandBone)
- Set Linear limits: X=Locked, Y=Locked, Z=Locked (or Free for dangling)
- Set Angular limits: Free (can rotate), or limited
Case Kinematic:
- StaticMeshComponent.SetSimulatePhysics(false)
- StaticMeshComponent.AttachToComponent(PlayerHandSocket)
Case Magnetic:
- Store target; handle in Tick with Lerp toward hand position
Step 6: Set GrabbedObject = TargetActor
Step 7: Set bIsGrabbing = true
Step 8: Fire OnObjectGrabbed(TargetActor)
Step 9: Return true
```
**Nodes Used:** `IsValid`, `Get Component by Class (StaticMeshComponent)`, `Is Simulate Physics Enabled`, `Get Mass`, `Create Constraint`, `SetConstrainedComponents`, `AttachToComponent`, `Branch`
#### `ReleaseObject(bThrow: Boolean)` → `void`
```
[Function: ReleaseObject]
Step 1: Branch on bIsGrabbing → If false, return
Step 2: Branch on bThrow AND bCanThrow:
True:
- Get PlayerCameraManager → Get Forward Vector
- Multiply forward vector by ThrowForce
- GrabbedObject.StaticMeshComponent.AddImpulse(throw vector)
- OR: if ConstraintComp exists → BreakConstraint, then AddImpulse
False:
- Just release without force
Step 3: Switch on DragMode:
- PhysicsConstraint: Destroy ConstraintComp
- Kinematic: DetachFromComponent, SetSimulatePhysics(true)
- Magnetic: Clear target reference
Step 4: Set GrabbedObject = None
Step 5: Set bIsGrabbing = false
Step 6: Fire OnObjectReleased(GrabbedObject, bThrow)
```
**Nodes Used:** `Get Forward Vector`, `Multiply (Vector * Float)`, `Add Impulse`, `Break Constraint`, `Destroy Component`, `Detach From Component`, `Set Simulate Physics`
#### `RotateObject(YawInput: Float, PitchInput: Float, RollInput: Float)` → `void`
```
[Function: RotateObject]
Step 1: Branch on bIsGrabbing → If false, return
Step 2: Create Rotator from inputs (use RotationSpeed multiplier)
- NewRotation = Make Rotator(PitchInput * RotationSpeed * DeltaTime, YawInput * RotationSpeed * DeltaTime, RollInput * RotationSpeed * DeltaTime)
Step 3: Switch on DragMode:
- PhysicsConstraint: GrabbedObject.AddLocalRotation(NewRotation)
- Kinematic: GrabbedObject.AddRelativeRotation(NewRotation)
- Magnetic: Rotate the lerp target
```
#### `SetHoldDistance(NewDistance: Float)` → `void`
```
[Function: SetHoldDistance]
Step 1: Clamp NewDistance between MinHoldDistance and MaxHoldDistance
Step 2: Set HoldDistance = NewDistance
Step 3: If DragMode == PhysicsConstraint:
- ConstraintComp.SetLinearPositionTarget(PlayerCamera.ForwardVector * HoldDistance)
Step 4: If DragMode == Kinematic:
- Set Relative Location (X = HoldDistance, Y = 0, Z = 0) on attached component
```
### 9.4 Event Dispatcher Bindings
| Bind to Dispatcher | Custom Event | Logic |
|-------------------|-------------|-------|
| Input Action: `IA_Grab` (Pressed) | `OnGrabPressed` | Get InteractionDetector.CurrentTarget → Call GrabObject |
| Input Action: `IA_Grab` (Released) | `OnGrabReleased` | Call ReleaseObject(true) |
| `BPC_InteractionDetector.OnTargetFound` | `OnGrabTargetFound(Target)` | Highlight grabbable object outline |
### 9.5 Networking
| Variable | Replication |
|----------|-------------|
| `bIsGrabbing` | `Replicated` |
| `GrabbedObject` | `Replicated` (Actor reference) |
**Server RPC:** `Server_GrabObject(TargetActor)` — server validates range, spawns constraint. Physics is server-authoritative; client predicts locally.
### 9.6 Blueprint Build Checklist
- [ ] Create BPC_PhysicsDragSystem component, add to Player Character
- [ ] Add all variables: DragMode, GrabbedObject, ConstraintComp, GrabDistance, HoldDistance, ThrowForce, RotationSpeed, bCanThrow, bIsGrabbing
- [ ] Implement GrabObject with three drag modes (PhysicsConstraint, Kinematic, Magnetic)
- [ ] Implement ReleaseObject with throw mechanic
- [ ] Implement RotateObject with input axis mapping
- [ ] Implement SetHoldDistance with scroll wheel input
- [ ] Bind to IA_Grab input action (pressed/released)
- [ ] Add MaxGrabMass config to prevent lifting impossibly heavy objects
- [ ] Test: grab crate, rotate, throw — physics should feel natural