using UnityEngine; namespace ProjectM.Client { /// /// Live-tunable knobs for the client-only COMBAT-FEEL slice (Stage E). A static bridge — mirrors /// — so values can be poked at runtime via MCP execute_code /// (e.g. ProjectM.Client.FeelConfig.HitShakeLocal = 0.4f;) WITHOUT a recompile, for interactive /// tuning. Read ONLY by client-presentation systems (, /// ) and the MonoBehaviour — all non-Burst, /// main-thread. NEVER read these from a [BurstCompile] system (managed-static + Color/enum-in-Burst /// hazards); they are presentation-only and never touch the deterministic simulation. /// /// Defaults match the values previously hardcoded in CombatFeedbackSystem so behaviour is byte-identical /// until a knob is poked. re-stamps every field on play-enter via /// [RuntimeInitializeOnLoadMethod(SubsystemRegistration)] because statics survive fast-enter-playmode /// domain reloads — without it a poked value would leak across play-enters and flash stale feel (the exact /// bug 's reset prevents). /// /// public static class FeelConfig { // ---- Feature 1: hit camera punch + (camera-only) hit-stop ---- /// Camera shake when the LOCAL player is hit (fed to PrototypeCameraRig.AddShake, clamp 0.8). public static float HitShakeLocal; /// Camera shake when a remote player / Husk is hit. public static float HitShakeRemote; /// Hit-spark particle burst count (procedural fallback path). public static int HitBurstCount; /// Hit SFX volume. public static float HitSfxVolume; /// Degrees of transient FOV "kick" on a LOCAL hit — the netcode-safe hit-stop (NEVER Time.timeScale). 0 = off. public static float HitStopFovKick; /// Milliseconds the FOV kick eases back to base. public static float HitStopDurationMs; // ---- Feature 1/2: death camera punch ---- /// Camera shake on LOCAL player death (loudest event by design). public static float PlayerDeathShake; /// Camera shake on a remote player's death. public static float RemotePlayerDeathShake; /// Base death-burst particle count (player death + Husk-death base). public static int DeathBurstCount; // ---- Feature 2: kill-shot fanfare (Husk death) ---- /// Camera shake on a Husk kill (nudged above a glancing hit, kept under PlayerDeathShake). public static float KillShake; /// Multiplier on DeathBurstCount for a Husk kill (result clamped by MaxActiveVfx). public static float KillBurstScale; /// Optional FOV kick on a kill (degrees). 0 = off. public static float KillFovKick; /// Husk-death SFX volume. public static float KillSfxVolume; // ---- Feature 3: respawn shimmer / fade-in (local player recovery) ---- /// Master gate for the local-player respawn shimmer. public static bool RespawnShimmerEnabled; /// Particle burst count for the recovery shimmer. public static int RespawnShimmerBurst; /// Light camera punch on recovery so respawn reads as "reinforcing". public static float RespawnShimmerShake; // ---- Feature 4: reticle lock-on tether (cosmetic aim HINT) ---- /// Master gate for the lock-on tether. public static bool LockOnEnabled; /// Show the tether only on the Gamepad scheme (mirrors the server's gamepad-only auto-target assist). public static bool LockOnGamepadOnly; /// Max world distance from the player to a tethered Husk. public static float LockOnRange; /// Forward half-arc (degrees) around PlayerFacing within which a Husk is eligible. public static float LockOnArcDegrees; /// Tether line tint (subtle highlight, not a laser). public static Color LockOnLineColor; /// Tether line width (world units). public static float LockOnLineWidth; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] public static void ResetDefaults() { // Feature 1 HitShakeLocal = 0.32f; HitShakeRemote = 0.10f; HitBurstCount = 10; HitSfxVolume = 0.70f; HitStopFovKick = 1.5f; HitStopDurationMs = 90f; // Feature 1/2 death PlayerDeathShake = 0.50f; RemotePlayerDeathShake = 0.25f; DeathBurstCount = 28; // Feature 2 kill-shot KillShake = 0.20f; KillBurstScale = 1.5f; KillFovKick = 1.0f; KillSfxVolume = 0.75f; // Feature 3 respawn RespawnShimmerEnabled = true; RespawnShimmerBurst = 24; RespawnShimmerShake = 0.12f; // Feature 4 tether LockOnEnabled = true; LockOnGamepadOnly = true; LockOnRange = 9.0f; LockOnArcDegrees = 60f; LockOnLineColor = new Color(0.55f, 0.9f, 1f, 0.35f); LockOnLineWidth = 0.05f; } } }