- 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.
232 lines
8.6 KiB
Markdown
232 lines
8.6 KiB
Markdown
# BPC_PhysicsDragSystem — Physics Drag System
|
||
|
||
**Parent Class:** `ActorComponent`
|
||
**Category:** Interaction
|
||
**Target UE Version:** 5.5–5.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 |