Add haptics example documentation for Project Void controller feedback
- Introduced comprehensive guide for setting up controller haptics and force feedback. - Detailed directory structure for haptic profiles and creation steps for DA_HapticProfile instances. - Included platform-specific configurations for Xbox and PS5 DualSense adaptive triggers. - Outlined wiring of BPC_HapticsController to various gameplay systems and events. - Provided accessibility integration options and testing checklist for haptic functionality.
This commit is contained in:
@@ -1,52 +1,178 @@
|
||||
# DA_HapticProfile — Data Asset
|
||||
|
||||
**Parent Class:** `UDataAsset`
|
||||
**Dependencies:** [`BPC_HapticsController`](../12-settings/)
|
||||
**Purpose:** Defines haptic feedback profiles for controller vibration and force feedback effects tied to gameplay events.
|
||||
**Parent Class:** `UPrimaryDataAsset`
|
||||
**Dependencies:** [`BPC_HapticsController`](../12-settings/148_BPC_HapticsController.md)
|
||||
**Purpose:** Defines haptic feedback profiles for controller vibration and force feedback effects tied to gameplay events. Each profile maps a GameplayTag to a platform-specific `UForceFeedbackEffect` waveform asset with configurable intensity, duration, motor mask, and priority.
|
||||
|
||||
---
|
||||
|
||||
## Enums Used
|
||||
|
||||
| Enum | Defined In | Values |
|
||||
|------|-----------|--------|
|
||||
| `EHapticEvent` | `BPC_HapticsController` (148) | Damage, HeavyDamage, Heartbeat, WeaponFire, WeaponReload, MeleeImpact, Footstep, Explosion, PickupItem, DropItem, GrabObject, ReleaseObject, ScareEvent, AmbientPulse, UI_Confirm, UI_Navigate, LowHealth, StaminaExhausted, Death |
|
||||
| `EHapticMotor` | `BPC_HapticsController` (148) | Left, Right, Both |
|
||||
|
||||
---
|
||||
|
||||
## Variables / Structure
|
||||
|
||||
### Core Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `ProfileTag` | `FGameplayTag` | Unique haptic profile identifier |
|
||||
| `EventType` | `EHapticEvent` | Damage, Heartbeat, Explosion, Footstep, WeaponFire, AmbientPulse |
|
||||
| `IntensityCurve` | `UCurveFloat*` | Vibration intensity over time |
|
||||
| `Duration` | `float` | Total haptic effect duration (seconds) |
|
||||
| `MotorMask` | `EHapticMotor` | Left, Right, Both |
|
||||
| `Priority` | `int32` | Higher priority overrides lower during conflicts |
|
||||
| `bCanInterrupt` | `bool` | Can this effect be interrupted by higher priority |
|
||||
| `PlatformMinIntensity` | `float` | Minimum intensity per platform capability |
|
||||
| `ProfileTag` | `FGameplayTag` | Unique haptic profile identifier (e.g., `Haptic.Damage.Heavy`) |
|
||||
| `EventType` | `EHapticEvent` | Event category this profile handles |
|
||||
| `ForceFeedbackEffect_Generic` | `UForceFeedbackEffect*` | Waveform curve asset for PC/Xbox generic controllers |
|
||||
| `ForceFeedbackEffect_PS5` | `UForceFeedbackEffect*` | Waveform curve asset for PS5 DualSense (higher fidelity) |
|
||||
| `ForceFeedbackEffect_Xbox` | `UForceFeedbackEffect*` | Waveform curve asset for Xbox controllers (optional override) |
|
||||
| `IntensityCurve` | `UCurveFloat*` | Optional: vibration intensity over time (0.0–1.0) |
|
||||
| `Duration` | `float` | Total haptic effect duration in seconds |
|
||||
| `MotorMask` | `EHapticMotor` | Left motor, Right motor, or Both |
|
||||
| `Priority` | `int32` | Higher priority overrides lower during conflicts (0 = lowest, 100 = highest) |
|
||||
| `bCanInterrupt` | `bool` | Can this effect be interrupted by a higher-priority effect? |
|
||||
| `bIgnoreTimeDilation` | `bool` | Should this play at real-time regardless of game speed? |
|
||||
|
||||
### Platform-Specific Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `PlatformMinIntensity` | `float` | Minimum intensity threshold before effect is felt (0.0–1.0) |
|
||||
| `DualSense_TriggerSide` | `FName` | PS5 adaptive trigger side ("Left", "Right", "None") |
|
||||
| `DualSense_TriggerEffect` | `FName` | PS5 trigger effect type ("Resistance", "Vibration", "WeaponFire", "BowDraw", "None") |
|
||||
| `DualSense_TriggerStartPosition` | `int32` | PS5 trigger position where effect begins (0–9) |
|
||||
| `DualSense_TriggerStrength` | `int32` | PS5 trigger effect strength (0–8) |
|
||||
|
||||
### Heartbeat-Specific Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `bIsHeartbeatProfile` | `bool` | Whether this profile is used for heartbeat pulse effects |
|
||||
| `TargetBPMRange_Min` | `float` | Minimum BPM this profile handles |
|
||||
| `TargetBPMRange_Max` | `float` | Maximum BPM this profile handles |
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Tags
|
||||
- Namespace: `Haptic.<Event>` (e.g., `Haptic.Damage.Heavy`, `Haptic.Heartbeat`)
|
||||
|
||||
- Namespace: `Haptic.<Category>.<Subcategory>`
|
||||
- Examples: `Haptic.Damage.Heavy`, `Haptic.Heartbeat.Normal`, `Haptic.WeaponFire.Pistol`
|
||||
- All tags must be registered in `DT_Tags_Player.csv` for validation at startup
|
||||
|
||||
### Full Tag Hierarchy
|
||||
|
||||
```
|
||||
Haptic.
|
||||
├── Damage.Light
|
||||
├── Damage.Heavy
|
||||
├── Damage.Critical
|
||||
├── Heartbeat.Normal
|
||||
├── Heartbeat.Fast
|
||||
├── Heartbeat.Panic
|
||||
├── WeaponFire.Pistol
|
||||
├── WeaponFire.Shotgun
|
||||
├── WeaponReload
|
||||
├── MeleeImpact.Crowbar
|
||||
├── MeleeImpact.Default
|
||||
├── Footstep.Tile
|
||||
├── Footstep.Wood
|
||||
├── Footstep.Concrete
|
||||
├── Footstep.Metal
|
||||
├── Footstep.Gravel
|
||||
├── Explosion
|
||||
├── Pickup.Item
|
||||
├── Pickup.Weapon
|
||||
├── Grab
|
||||
├── Release.Throw
|
||||
├── Scare.JumpScare
|
||||
├── Scare.TensionRise
|
||||
├── Ambient.Void
|
||||
├── Ambient.Default
|
||||
├── LowHealth
|
||||
├── StaminaExhausted
|
||||
├── Death
|
||||
├── UI.Confirm
|
||||
└── UI.Navigate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Rules
|
||||
- `ProfileTag` must be unique
|
||||
- `Duration` must be > 0
|
||||
- `IntensityCurve` must be valid
|
||||
|
||||
- `ProfileTag` must be unique across all profiles
|
||||
- `Duration` must be > 0.0
|
||||
- At least one `ForceFeedbackEffect_*` must be assigned (Generic falls back for all platforms)
|
||||
- `Priority` must be 0–100
|
||||
- If `bIsHeartbeatProfile` is true, `TargetBPMRange_Min` and `TargetBPMRange_Max` must be set
|
||||
- If `DualSense_TriggerSide != "None"`, trigger effect fields must be valid
|
||||
|
||||
---
|
||||
|
||||
## Example Data
|
||||
|
||||
### Damage Profile — Heavy Hit
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| ProfileTag | `Haptic.Damage.Critical` |
|
||||
| EventType | Damage |
|
||||
| Duration | 0.5 |
|
||||
| MotorMask | Both |
|
||||
| Priority | 10 |
|
||||
| `ProfileTag` | `Haptic.Damage.Heavy` |
|
||||
| `EventType` | `HeavyDamage` |
|
||||
| `Duration` | `0.4` |
|
||||
| `MotorMask` | `Both` |
|
||||
| `Priority` | `80` |
|
||||
| `bCanInterrupt` | `true` |
|
||||
| `bIgnoreTimeDilation` | `true` |
|
||||
| `ForceFeedbackEffect_Generic` | `FFE_Damage_Heavy` |
|
||||
| `ForceFeedbackEffect_PS5` | `FFE_Damage_Heavy_PS5` |
|
||||
|
||||
### Heartbeat Profile — Normal
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| `ProfileTag` | `Haptic.Heartbeat.Normal` |
|
||||
| `EventType` | `Heartbeat` |
|
||||
| `Duration` | `0.1` |
|
||||
| `MotorMask` | `Left` |
|
||||
| `Priority` | `30` |
|
||||
| `bCanInterrupt` | `true` |
|
||||
| `bIsHeartbeatProfile` | `true` |
|
||||
| `TargetBPMRange_Min` | `60.0` |
|
||||
| `TargetBPMRange_Max` | `90.0` |
|
||||
| `ForceFeedbackEffect_Generic` | `FFE_Heartbeat` |
|
||||
|
||||
### Weapon Fire — Pistol
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| `ProfileTag` | `Haptic.WeaponFire.Pistol` |
|
||||
| `EventType` | `WeaponFire` |
|
||||
| `Duration` | `0.08` |
|
||||
| `MotorMask` | `Right` |
|
||||
| `Priority` | `50` |
|
||||
| `DualSense_TriggerSide` | `Right` |
|
||||
| `DualSense_TriggerEffect` | `WeaponFire` |
|
||||
| `DualSense_TriggerStartPosition` | `4` |
|
||||
| `DualSense_TriggerStrength` | `6` |
|
||||
|
||||
---
|
||||
|
||||
## Consumed By
|
||||
- [`BPC_HapticsController`](../12-settings/)
|
||||
- [`BPC_HapticsController`](../12-settings/148_BPC_HapticsController.md) — loads all profiles into `HapticProfileMap` at initialization
|
||||
|
||||
## Referenced By
|
||||
- `BPC_HealthSystem` (08) — damage haptics
|
||||
- `BPC_FirearmSystem` (74) — weapon fire haptics
|
||||
- `BPC_MeleeSystem` (76) — melee impact haptics
|
||||
- `BPC_ScareEventSystem` (101) — scare event haptics
|
||||
- `BPC_MovementStateSystem` (11) — footstep haptics
|
||||
- `BPC_ReloadSystem` (78) — reload haptics
|
||||
- `BPC_PhysicsDragSystem` (22) — grab/release haptics
|
||||
- `BP_ItemPickup` (25) — pickup haptics
|
||||
- `BPC_DeathHandlingSystem` (39) — death haptics
|
||||
- `BPC_StaminaSystem` (09) — stamina exhausted haptics
|
||||
|
||||
---
|
||||
|
||||
## Reuse Notes
|
||||
- Haptic profiles are platform-agnostic; translation handled by PlatformServiceAbstraction
|
||||
- Haptic profiles are platform-agnostic in design; `BPC_HapticsController` selects the correct `UForceFeedbackEffect` asset at runtime based on `CurrentPlatform`.
|
||||
- Designers create FFE waveform curves in the Content Browser — no Blueprint changes needed for tuning.
|
||||
- For heartbeat profiles: create 3 instances (Normal 60-90 BPM, Fast 90-140 BPM, Panic 140-180 BPM). `BPC_HapticsController` auto-selects based on current BPM.
|
||||
- For footstep profiles: create one per surface type. `BPC_MovementStateSystem` selects based on physical surface trace result.
|
||||
- Priority guidelines: 0–20 (ambient/footsteps), 30–50 (weapons/reload/pickups), 60–80 (damage), 90–100 (scares/death).
|
||||
- The `Haptic.` namespace should be registered in `DT_Tags_Player.csv` so `DA_GameTagRegistry` validates them at startup.
|
||||
|
||||
Reference in New Issue
Block a user