How-To: Expose Another Plugin's Settings
Goal: surface options that belong to a different plugin (camera, input, a gameplay system) in a settings screen - without CrimsonSettings depending on that plugin, and without adding fields to CrimsonSettings. The keyed store makes this a data-authoring task, not a code-coupling one.
Key -> value pairs; it never names a camera or gameplay concept. The consuming module (which already sees both plugins) reads those keys and applies them. So neither plugin gains a dependency on the other.1. Author the options with storage keys
Add the options to a settings data asset section, tick Persist To Shared Store, and give each a stable, namespaced Storage Key. For camera options, CrimsonCore reads these exact keys:
Images/CrimsonSettings/howto-expose-dataasset.png| Option | Type | Storage Key |
|---|---|---|
| Field of view | Scalar | Camera.FieldOfView |
| Screen-shake intensity | Scalar | Camera.ShakeScale |
| Default zoom | Scalar | Camera.ZoomDistance |
| Shoulder side | Discrete | Camera.Shoulder |
| Occlusion on/off | Discrete | Camera.OcclusionEnabled |
| Occlusion strength | Scalar | Camera.OcclusionStrength |
| Lock-on indicators | Discrete | Camera.LockOnIndicators |
| Camera lag on/off + speed | Discrete + Scalar | Camera.LagEnabled / Camera.LagSpeed |
| Auto-recenter on/off + delay/speed | Discrete + Scalar | Camera.AutoRecenterEnabled / Camera.AutoRecenterDelay / Camera.AutoRecenterInterpSpeed |
2. Apply the values in a module that sees both plugins
A consumer reads the keys and pushes them onto the target system. For camera, CrimsonCore already does this for you: its player camera manager reads the Camera.* keys each frame and calls the CrimsonCamera runtime setters (SetFieldOfViewOverride, SetCameraShakeScale, SetOcclusionEnabled, the lag/recenter setters, ...). For your own system, mirror the pattern:
// In YOUR module (which depends on CrimsonSettings AND the target plugin):if (UCrimsonSharedSettingsSubsystem* Sub = UCrimsonSharedSettingsSubsystem::Get(LocalPlayer)){if (UCrimsonSettingsShared* S = Sub->GetSharedSettings()){Camera->SetFieldOfViewOverride(S->GetFloatValue(FName("Camera.FieldOfView"), 0.f));Occlusion->SetOcclusionEnabled(S->GetBoolValue(FName("Camera.OcclusionEnabled"), true));}}// Re-apply on UCrimsonSettingsShared::OnSettingChanged so live edits take effect.
UCrimsonSettingsShared broadcasts OnSettingChanged whenever any keyed value changes, and UCrimsonSharedSettingsSubsystem auto-saves on a short debounce. Subscribe to that event to re-apply live while the player drags a slider.See also
- CrimsonCamera wiki -> How-To: Expose Camera Options as User Settings - the runtime setters this drives.
- Concept: Storage Model - the keyed store and the shared-settings subsystem.
- How-To: Persist Settings with Zero Glue - the authoring half of this pattern.