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:
@@ -583,11 +583,12 @@ Each game asset proves a specific framework system works. Below: every framework
|
||||
| 102 | BPC_ProgressStatTracker | Total playtime, collectibles found, enemies killed |
|
||||
| 103 | SS_AchievementSystem | "First Light" (flashlight), "Untouchable" (no-damage run) |
|
||||
|
||||
### 12-settings (Settings — 2 systems)
|
||||
### 12-settings (Settings — 3 systems)
|
||||
| # | Framework System | Demonstrated By |
|
||||
|---|----------------|----------------|
|
||||
| 104 | BPC_AccessibilitySettings | Subtitle toggle, colorblind mode, controller remap |
|
||||
| 105 | SS_SettingsSystem | Audio/Video/Controls persistent settings |
|
||||
| 148 | BPC_HapticsController | Controller vibration: damage, weapon fire, heartbeat, footsteps, scares. Attached to PC_HorrorController |
|
||||
|
||||
### 13-polish (Polish — 9 systems)
|
||||
| # | Framework System | Demonstrated By |
|
||||
@@ -691,6 +692,7 @@ Each `docs/game/` file explains how to build a specific section of the prototype
|
||||
| [`save-checkpoints.md`](save-checkpoints.md) | Save system, checkpoints, death loop, void space, persistence | 15 |
|
||||
| [`polish-loading-credits.md`](polish-loading-credits.md) | Tutorials, loading screen, credits, debug, analytics | 19, 20 |
|
||||
| [`state-gating-examples.md`](state-gating-examples.md) | DA_StateGatingTable game-specific rules | 14 |
|
||||
| [`haptics-example.md`](haptics-example.md) | Controller haptics — damage, weapons, heartbeat, scares, platform tuning | 5, 10, 13, 14 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
438
docs/game/haptics-example.md
Normal file
438
docs/game/haptics-example.md
Normal file
@@ -0,0 +1,438 @@
|
||||
# Haptics Example — Project Void Controller Feedback
|
||||
|
||||
**Version:** 1.0 | **Target UE:** 5.5–5.7 | **Framework System:** BPC_HapticsController (148) + DA_HapticProfile (121)
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
This document walks through setting up controller haptics/force feedback in the **Project Void** horror game prototype. It covers creating `DA_HapticProfile` Data Asset instances for every gameplay event, wiring `BPC_HapticsController` to all relevant systems, and platform-specific tuning for Xbox rumble and PS5 DualSense adaptive triggers.
|
||||
|
||||
**Rule:** All game haptic content lives in `Content/Game/DataAssets/Haptics/`. Never modify `Content/Framework/Settings/BPC_HapticsController`.
|
||||
|
||||
---
|
||||
|
||||
## Game Haptics Directory Structure
|
||||
|
||||
```
|
||||
Content/Game/DataAssets/
|
||||
├── Haptics/ ← ALL game haptic profiles
|
||||
│ ├── DA_Haptic_Damage_Light.uasset
|
||||
│ ├── DA_Haptic_Damage_Heavy.uasset
|
||||
│ ├── DA_Haptic_Heartbeat_Normal.uasset
|
||||
│ ├── DA_Haptic_Heartbeat_Fast.uasset
|
||||
│ ├── DA_Haptic_Weapon_Pistol.uasset
|
||||
│ ├── DA_Haptic_Weapon_Shotgun.uasset
|
||||
│ ├── DA_Haptic_Weapon_Crowbar.uasset
|
||||
│ ├── DA_Haptic_Reload.uasset
|
||||
│ ├── DA_Haptic_Footstep_Tile.uasset
|
||||
│ ├── DA_Haptic_Footstep_Wood.uasset
|
||||
│ ├── DA_Haptic_Footstep_Concrete.uasset
|
||||
│ ├── DA_Haptic_Explosion.uasset
|
||||
│ ├── DA_Haptic_Pickup_Item.uasset
|
||||
│ ├── DA_Haptic_Pickup_Weapon.uasset
|
||||
│ ├── DA_Haptic_Grab_Object.uasset
|
||||
│ ├── DA_Haptic_Release_Throw.uasset
|
||||
│ ├── DA_Haptic_Scare_JumpScare.uasset
|
||||
│ ├── DA_Haptic_Scare_TensionRise.uasset
|
||||
│ ├── DA_Haptic_Ambient_Void.uasset
|
||||
│ ├── DA_Haptic_LowHealth.uasset
|
||||
│ ├── DA_Haptic_StaminaExhaust.uasset
|
||||
│ ├── DA_Haptic_Death.uasset
|
||||
│ ├── DA_Haptic_UI_Confirm.uasset
|
||||
│ └── DA_Haptic_UI_Navigate.uasset
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create DA_HapticProfile Data Asset Instances
|
||||
|
||||
For each event below, create a Data Asset instance in the Content Browser.
|
||||
|
||||
### How to Create a Haptic Profile
|
||||
|
||||
1. Navigate to `Content/Game/DataAssets/Haptics/`
|
||||
2. Right-click → **Miscellaneous → Data Asset**
|
||||
3. Select class: `DA_HapticProfile`
|
||||
4. Name: `DA_Haptic_{Event}` (see table below)
|
||||
5. Open the asset → fill in the fields:
|
||||
- **ProfileTag:** The GameplayTag for this effect (e.g., `Haptic.Damage.Light`)
|
||||
- **EventType:** Select from `EHapticEvent` enum
|
||||
- **ForceFeedbackEffect:** Assign the `UForceFeedbackEffect` waveform curve asset
|
||||
- **IntensityCurve:** Optional `UCurveFloat` for intensity over time
|
||||
- **Duration:** Total effect seconds
|
||||
- **MotorMask:** Left, Right, or Both
|
||||
- **Priority:** 0 (lowest, like footsteps) to 100 (highest, like death)
|
||||
- **bCanInterrupt:** Whether lower-priority effects can interrupt this
|
||||
- **PlatformMinIntensity:** Minimum intensity before effect is felt
|
||||
|
||||
### Complete Haptic Profile Data Table
|
||||
|
||||
| Asset Name | GameplayTag | EventType | Duration | Motor | Priority | Trigger Condition |
|
||||
|------------|------------|-----------|----------|-------|----------|-------------------|
|
||||
| `DA_Haptic_Damage_Light` | `Haptic.Damage.Light` | Damage | 0.15s | Both | 60 | Player takes ≤10 damage |
|
||||
| `DA_Haptic_Damage_Heavy` | `Haptic.Damage.Heavy` | HeavyDamage | 0.4s | Both | 80 | Player takes >30 damage |
|
||||
| `DA_Haptic_Damage_Critical` | `Haptic.Damage.Critical` | HeavyDamage | 0.6s | Both | 90 | Player HP <10% and hit |
|
||||
| `DA_Haptic_Heartbeat_Normal` | `Haptic.Heartbeat.Normal` | Heartbeat | 0.1s | Left | 30 | BPM 60–90 (calm/tense) |
|
||||
| `DA_Haptic_Heartbeat_Fast` | `Haptic.Heartbeat.Fast` | Heartbeat | 0.08s | Left | 40 | BPM 90–140 (scared) |
|
||||
| `DA_Haptic_Heartbeat_Panic` | `Haptic.Heartbeat.Panic` | Heartbeat | 0.05s | Both | 50 | BPM 140–180 (panic) |
|
||||
| `DA_Haptic_Weapon_Pistol` | `Haptic.WeaponFire.Pistol` | WeaponFire | 0.08s | Right | 50 | Pistol fired |
|
||||
| `DA_Haptic_Weapon_Shotgun` | `Haptic.WeaponFire.Shotgun` | WeaponFire | 0.25s | Both | 70 | Shotgun fired |
|
||||
| `DA_Haptic_Weapon_Crowbar` | `Haptic.MeleeImpact.Crowbar` | MeleeImpact | 0.15s | Both | 55 | Crowbar hits enemy |
|
||||
| `DA_Haptic_Reload` | `Haptic.WeaponReload` | WeaponReload | 0.1s | Right | 40 | Reload magazine click |
|
||||
| `DA_Haptic_Footstep_Tile` | `Haptic.Footstep.Tile` | Footstep | 0.02s | Left | 10 | Walking on tile floor |
|
||||
| `DA_Haptic_Footstep_Wood` | `Haptic.Footstep.Wood` | Footstep | 0.03s | Left | 10 | Walking on wood floor |
|
||||
| `DA_Haptic_Footstep_Concrete` | `Haptic.Footstep.Concrete` | Footstep | 0.04s | Both | 10 | Walking on concrete |
|
||||
| `DA_Haptic_Explosion` | `Haptic.Explosion` | Explosion | 0.6s | Both | 85 | Nearby explosion |
|
||||
| `DA_Haptic_Pickup_Item` | `Haptic.Pickup.Item` | PickupItem | 0.05s | Right | 20 | Item picked up |
|
||||
| `DA_Haptic_Pickup_Weapon` | `Haptic.Pickup.Weapon` | PickupItem | 0.1s | Both | 25 | Weapon equipped |
|
||||
| `DA_Haptic_Grab_Object` | `Haptic.Grab` | GrabObject | 0.08s | Both | 35 | Physics object grabbed |
|
||||
| `DA_Haptic_Release_Throw` | `Haptic.Release.Throw` | ReleaseObject | 0.12s | Both | 35 | Physics object thrown |
|
||||
| `DA_Haptic_Scare_JumpScare` | `Haptic.Scare.JumpScare` | ScareEvent | 0.5s | Both | 95 | Jump scare triggers |
|
||||
| `DA_Haptic_Scare_TensionRise` | `Haptic.Scare.TensionRise` | ScareEvent | 2.0s | Left | 65 | Ambient tension building |
|
||||
| `DA_Haptic_Ambient_Void` | `Haptic.Ambient.Void` | AmbientPulse | 3.0s | Left | 15 | Void Space ambient rumble |
|
||||
| `DA_Haptic_LowHealth` | `Haptic.LowHealth` | LowHealth | 0.2s | Both | 75 | HP drops below 25% |
|
||||
| `DA_Haptic_StaminaExhaust` | `Haptic.StaminaExhausted` | StaminaExhausted | 0.3s | Both | 45 | Stamina reaches zero |
|
||||
| `DA_Haptic_Death` | `Haptic.Death` | Death | 0.8s | Both | 100 | Player dies |
|
||||
| `DA_Haptic_UI_Confirm` | `Haptic.UI.Confirm` | UI_Confirm | 0.03s | Right | 5 | Menu option selected |
|
||||
| `DA_Haptic_UI_Navigate` | `Haptic.UI.Navigate` | UI_Navigate | 0.02s | Right | 5 | Menu cursor moved |
|
||||
|
||||
### Creating ForceFeedbackEffect Assets (Waveform Curves)
|
||||
|
||||
For each haptic profile that uses a `UForceFeedbackEffect`:
|
||||
|
||||
1. Navigate to `Content/Game/DataAssets/Haptics/Curves/`
|
||||
2. Right-click → **Miscellaneous → Force Feedback Effect**
|
||||
3. Name: `FFE_{Event}` (e.g., `FFE_Damage_Light`)
|
||||
4. Open the asset:
|
||||
- Add a channel: **Left Large** (low frequency rumble motor)
|
||||
- Add a channel: **Right Small** (high frequency precision motor)
|
||||
- For the Damage Light curve: short spike at 0.5 intensity, 0.15s duration
|
||||
- For the Shotgun curve: heavy dual-motor spike, 0.25s duration
|
||||
- For the Heartbeat curve: single low-frequency pulse at 0.1s
|
||||
5. Assign the FFE asset to the corresponding `DA_HapticProfile`
|
||||
|
||||
### Platform-Specific Force Feedback Assets
|
||||
|
||||
For PS5 DualSense-only effects, create separate FFE assets in `Curves/PS5/`:
|
||||
- `FFE_Damage_Heavy_PS5` — higher fidelity trigger and haptic pattern
|
||||
- `FFE_Shotgun_PS5` — trigger kick + body rumble simultaneously
|
||||
- `FFE_Heartbeat_PS5` — pulse on both adaptive triggers
|
||||
|
||||
The `BPC_HapticsController` selects the right asset at runtime based on `CurrentPlatform`.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Wiring BPC_HapticsController to Gameplay Systems
|
||||
|
||||
### 2.1 Player Damage → Haptic
|
||||
|
||||
In `BP_HorrorPlayerCharacter` (or wherever `BPC_HealthSystem` is attached):
|
||||
|
||||
```
|
||||
[In BPC_HealthSystem: OnTakeDamage Event]
|
||||
→ Get BPC_HapticsController from Owner (PlayerController)
|
||||
→ Branch on damage amount:
|
||||
≤10: PlayHapticByTag(Haptic.Damage.Light, 1.0)
|
||||
10–30: PlayHapticByTag(Haptic.Damage.Heavy, 1.0)
|
||||
>30: PlayHapticByTag(Haptic.Damage.Critical, 1.0)
|
||||
→ Branch on current health / max health:
|
||||
<0.25: PlayHapticByTag(Haptic.LowHealth, 1.0)
|
||||
```
|
||||
|
||||
### 2.2 Weapon Fire → Haptic
|
||||
|
||||
In `BP_Pistol_Held` and `BP_Shotgun_Held` (or the `BPC_FirearmSystem`):
|
||||
|
||||
```
|
||||
[In BPC_FirearmSystem: OnFire Event]
|
||||
→ Get Owner PlayerController → Get BPC_HapticsController
|
||||
→ Switch on equipped weapon:
|
||||
Pistol: PlayHapticByTag(Haptic.WeaponFire.Pistol, 1.0)
|
||||
Shotgun: PlayHapticByTag(Haptic.WeaponFire.Shotgun, 1.0)
|
||||
```
|
||||
|
||||
For DualSense adaptive triggers (PS5 only — no-op on other platforms):
|
||||
|
||||
```
|
||||
[AimDownSights pressed]
|
||||
→ if IsDualSenseConnected:
|
||||
→ SetDualSenseTriggerEffect("Right", "WeaponFire", 2, 5) ← R2 stiffens at position 2
|
||||
|
||||
[AimDownSights released]
|
||||
→ if IsDualSenseConnected:
|
||||
→ SetDualSenseTriggerEffect("Right", "Resistance", 0, 0) ← Remove trigger resistance
|
||||
```
|
||||
|
||||
### 2.3 Reload → Haptic
|
||||
|
||||
```
|
||||
[In BPC_ReloadSystem: ReloadComplete Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ PlayHapticByTag(Haptic.WeaponReload, 1.0)
|
||||
```
|
||||
|
||||
### 2.4 Melee → Haptic
|
||||
|
||||
```
|
||||
[In BPC_MeleeSystem: OnMeleeHit Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ PlayHapticByTag(Haptic.MeleeImpact.Crowbar, 1.0)
|
||||
```
|
||||
|
||||
### 2.5 Heartbeat → Continuous Haptic
|
||||
|
||||
In `PC_HorrorController` (child of PlayerController with `BPC_HapticsController` attached):
|
||||
|
||||
```
|
||||
[Event BeginPlay]
|
||||
→ Get Pawn → Get BPC_StateManager
|
||||
→ Bind Event OnHeartRateChanged → [Custom Event]
|
||||
|
||||
[Custom Event: OnHeartRateChanged(BPM)]
|
||||
→ Get BPC_HapticsController (self)
|
||||
→ PlayHeartbeatHaptic(BPM) ← This starts/stops the looping heartbeat pulse
|
||||
```
|
||||
|
||||
The heartbeat haptic automatically switches profiles based on BPM range:
|
||||
|
||||
```
|
||||
In PlayHapticByTag (heartbeat):
|
||||
→ Clamp BPM to 40–180
|
||||
→ Select profile:
|
||||
BPM 40–90: Haptic.Heartbeat.Normal (slow pulse on left motor)
|
||||
BPM 90–140: Haptic.Heartbeat.Fast (faster pulse, stronger)
|
||||
BPM 140–180: Haptic.Heartbeat.Panic (both motors, double-pulse)
|
||||
```
|
||||
|
||||
### 2.6 Footsteps → Surface-Dependent Haptic
|
||||
|
||||
In GASP animation notifies or `BPC_MovementStateSystem`:
|
||||
|
||||
```
|
||||
[Animation Notify: Footstep]
|
||||
→ Physical Surface Trace → Get Surface Type (Tile, Wood, Concrete, Carpet, Metal)
|
||||
→ Get BPC_HapticsController
|
||||
→ Switch on Surface:
|
||||
Tile: PlayHapticByTag(Haptic.Footstep.Tile, surfaceDependentIntensity)
|
||||
Wood: PlayHapticByTag(Haptic.Footstep.Wood, surfaceDependentIntensity)
|
||||
Concrete: PlayHapticByTag(Haptic.Footstep.Concrete, surfaceDependentIntensity)
|
||||
Metal: PlayHapticByTag(Haptic.Footstep.Metal, surfaceDependentIntensity)
|
||||
Carpet: Skip (no haptic on soft surfaces)
|
||||
→ Scale intensity by movement speed:
|
||||
Sneak (0.3x), Walk (1.0x), Sprint (1.5x)
|
||||
```
|
||||
|
||||
### 2.7 Scare Events → Haptic
|
||||
|
||||
```
|
||||
[In BPC_ScareEventSystem: OnScareTriggered(ScareType)]
|
||||
→ Get BPC_HapticsController
|
||||
→ Switch on ScareType:
|
||||
JumpScare: PlayHapticByTag(Haptic.Scare.JumpScare, 1.0)
|
||||
TensionRise: PlayHapticByTag(Haptic.Scare.TensionRise, 1.0)
|
||||
→ This plays a 2s ramp-up rumble on the left motor
|
||||
```
|
||||
|
||||
### 2.8 Void Space Ambient → Continuous Tension Rumble
|
||||
|
||||
```
|
||||
[In BP_AtmosphereController_WardA: EnterVoidSpace Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ PlayHapticByTag(Haptic.Ambient.Void, 0.6) ← Low-intensity ambient rumble
|
||||
|
||||
[ExitVoidSpace Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ StopHaptic ← Stop all ambient
|
||||
```
|
||||
|
||||
### 2.9 Death → Final Rumble
|
||||
|
||||
```
|
||||
[In BPC_DeathHandlingSystem: OnDeath Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ PlayHapticByTag(Haptic.Death, 1.0)
|
||||
```
|
||||
|
||||
### 2.10 Stamina Exhausted → Warning Pulse
|
||||
|
||||
```
|
||||
[In BPC_StaminaSystem: Stamina = 0 Event]
|
||||
→ Get BPC_HapticsController
|
||||
→ PlayHapticByTag(Haptic.StaminaExhausted, 1.0)
|
||||
```
|
||||
|
||||
### 2.11 UI Navigation → Subtle Clicks
|
||||
|
||||
```
|
||||
[In WBP_MainMenu or WBP_PauseMenu: OnButtonHovered / OnSelectionChanged]
|
||||
→ Get BPC_HapticsController (from owning PlayerController)
|
||||
→ PlayHapticByTag(Haptic.UI.Navigate, 1.0)
|
||||
|
||||
[OnButtonPressed / Confirm]
|
||||
→ PlayHapticByTag(Haptic.UI.Confirm, 1.0)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Platform-Specific Configuration
|
||||
|
||||
### 3.1 Xbox Controller Settings
|
||||
|
||||
Xbox controllers use standard dual-motor rumble (Left = low frequency, Right = high frequency). No special setup required beyond creating `UForceFeedbackEffect` assets.
|
||||
|
||||
For Xbox-specific tuning:
|
||||
- Left motor (low frequency): Use for heavy impacts, explosions, death
|
||||
- Right motor (high frequency): Use for weapon fire, reload clicks, UI feedback
|
||||
- Both motors: Use for damage, jump scares, melee impacts
|
||||
|
||||
### 3.2 PS5 DualSense Adaptive Triggers
|
||||
|
||||
The DualSense supports two trigger effect types via the PS5 Controller Plugin:
|
||||
|
||||
| Effect Type | Description | Use Case |
|
||||
|------------|-------------|----------|
|
||||
| `Resistance` | Trigger stiffens at a certain press point | Aiming down sights (R2) |
|
||||
| `Vibration` | Trigger motor vibrates | Weapon fire kick on R2 |
|
||||
| `WeaponFire` | Simulated trigger break | Pulling trigger on pistol/shotgun |
|
||||
| `BowDraw` | Increasing resistance as trigger pulls | (future: bow weapon) |
|
||||
| `AutomaticRifle` | Rapid trigger vibration | (future: automatic rifles) |
|
||||
|
||||
**Trigger Effect Parameters:**
|
||||
- `StartPosition`: Where on the trigger pull the effect begins (0 = fully released, 9 = fully pressed)
|
||||
- `Strength`: Effect intensity (0 = off, 8 = maximum)
|
||||
- `EndPosition` (Resistance only): Where the resistance wall ends
|
||||
|
||||
**Example: Pistol trigger effect:**
|
||||
```
|
||||
WeaponFire effect:
|
||||
StartPosition = 4 ← Effect starts midway through pull
|
||||
Strength = 6 ← Moderate break-point feel
|
||||
```
|
||||
|
||||
**Graceful fallback:** On Xbox/PC, `SetDualSenseTriggerEffect` is a no-op. No crash, no error.
|
||||
|
||||
### 3.3 Controller Speaker Audio (PS5)
|
||||
|
||||
The DualSense has a small speaker. Use it sparingly for immersion:
|
||||
|
||||
| Game Event | Speaker Audio |
|
||||
|------------|--------------|
|
||||
| Radio crackle | When near a working radio or walkie-talkie |
|
||||
| Heartbeat | Quiet heartbeat thump when stress is high |
|
||||
| Key jingle | When picking up keys |
|
||||
| Flashlight click | Mechanical click when toggling flashlight |
|
||||
|
||||
**Implementation:**
|
||||
1. Create `USoundWave` or `UMetaSoundSource` assets
|
||||
2. Route through `SS_AudioManager` with `Bus = Dialogue` (or a dedicated `Speaker` sub-bus)
|
||||
3. `SS_AudioManager` detects platform and routes to controller speaker on PS5, falls back to main output on other platforms
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Accessibility Integration
|
||||
|
||||
### Settings Menu Integration
|
||||
|
||||
In `WBP_SettingsMenu` (or `WBP_AccessibilityUI`), add a **Haptics** section:
|
||||
|
||||
```
|
||||
Haptics Settings:
|
||||
├── [Toggle] Controller Vibration: ON/OFF
|
||||
│ └─ Calls BPC_AccessibilitySettings.SetHapticsEnabled(bool)
|
||||
│ └─ Dispatcher → BPC_HapticsController.SetHapticsEnabled()
|
||||
├── [Slider] Vibration Intensity: 0% – 100%
|
||||
│ └─ Sets BPC_HapticsController.HapticIntensityScale
|
||||
├── [Toggle] Adaptive Triggers (PS5 Only): ON/OFF
|
||||
│ └─ Sets BPC_HapticsController.bEnableDualSenseTriggers
|
||||
└── [Toggle] Controller Speaker (PS5 Only): ON/OFF
|
||||
└─ Sets BPC_HapticsController.bEnableSpeakerAudio
|
||||
```
|
||||
|
||||
### Accessibility Presets
|
||||
|
||||
Provide preset profiles:
|
||||
- **Full Haptics** (default): All effects on, full intensity
|
||||
- **Reduced Haptics:** Half intensity, no ambient rumble, no trigger effects
|
||||
- **No Haptics:** All vibration off (accessibility minimum)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Testing Checklist
|
||||
|
||||
### Basic Functionality
|
||||
- [ ] Pick up an item → controller vibrates briefly
|
||||
- [ ] Fire pistol → right motor kicks
|
||||
- [ ] Fire shotgun → both motors heavy kick
|
||||
- [ ] Take damage → vibration intensity scales with damage amount
|
||||
- [ ] Heartbeat BPM increases when enemy nearby → pulse speeds up
|
||||
- [ ] Walk on tile floor → light footstep ticks on left motor
|
||||
- [ ] Sprint on concrete → heavier footstep pulses on both motors
|
||||
- [ ] Jump scare triggers → intense 0.5s dual-motor rumble
|
||||
- [ ] Enter Void Space → low continuous ambient rumble starts
|
||||
- [ ] Leave Void Space → ambient rumble stops
|
||||
- [ ] Death → final heavy 0.8s rumble plays
|
||||
|
||||
### Platform
|
||||
- [ ] Xbox controller: all effects work (standard rumble)
|
||||
- [ ] PS5 DualSense: adaptive triggers stiffen when aiming
|
||||
- [ ] PS5 DualSense: trigger kick on weapon fire
|
||||
- [ ] PS4 DualShock: falls back to standard rumble
|
||||
- [ ] PC keyboard/mouse: no vibration (expected — no controller connected)
|
||||
- [ ] Controller hot-swap: new platform detected, correct profiles load
|
||||
|
||||
### Accessibility
|
||||
- [ ] Toggle vibration OFF in settings → no haptic effects play
|
||||
- [ ] Toggle vibration ON again → haptics resume
|
||||
- [ ] Reduce intensity to 50% → all effects half strength
|
||||
- [ ] Disable adaptive triggers → trigger effects stop on PS5
|
||||
|
||||
### Edge Cases
|
||||
- [ ] Rapid weapon fire → respects MinTimeBetweenEffects, no rumble spam
|
||||
- [ ] Damage + weapon fire simultaneously → higher priority damage wins
|
||||
- [ ] Heartbeat continues during combat — doesn't overwhelm other effects
|
||||
- [ ] Controller disconnected mid-gameplay → no crash, haptics gracefully stop
|
||||
- [ ] Load save file → haptics settings restored from SS_SettingsSystem
|
||||
|
||||
---
|
||||
|
||||
## Haptic GameplayTag Reference
|
||||
|
||||
All tags are in the `Haptic.` namespace, registered in `DT_Tags_Player.csv`:
|
||||
|
||||
```
|
||||
Haptic.Damage.Light
|
||||
Haptic.Damage.Heavy
|
||||
Haptic.Damage.Critical
|
||||
Haptic.Heartbeat.Normal
|
||||
Haptic.Heartbeat.Fast
|
||||
Haptic.Heartbeat.Panic
|
||||
Haptic.WeaponFire.Pistol
|
||||
Haptic.WeaponFire.Shotgun
|
||||
Haptic.WeaponReload
|
||||
Haptic.MeleeImpact.Crowbar
|
||||
Haptic.MeleeImpact.Default
|
||||
Haptic.Footstep.Tile
|
||||
Haptic.Footstep.Wood
|
||||
Haptic.Footstep.Concrete
|
||||
Haptic.Footstep.Metal
|
||||
Haptic.Footstep.Gravel
|
||||
Haptic.Explosion
|
||||
Haptic.Pickup.Item
|
||||
Haptic.Pickup.Weapon
|
||||
Haptic.Grab
|
||||
Haptic.Release.Throw
|
||||
Haptic.Scare.JumpScare
|
||||
Haptic.Scare.TensionRise
|
||||
Haptic.Ambient.Void
|
||||
Haptic.Ambient.Default
|
||||
Haptic.LowHealth
|
||||
Haptic.StaminaExhausted
|
||||
Haptic.Death
|
||||
Haptic.UI.Confirm
|
||||
Haptic.UI.Navigate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Haptics Example v1.0 — Part of the Project Void horror game prototype. Framework systems: BPC_HapticsController (148), DA_HapticProfile (121).*
|
||||
Reference in New Issue
Block a user