Files
Project-M/Assets/_Project/Scripts/Client/Presentation/AmbientMotionConfig.cs
T
kronic 9670465e25 World: flora feel fix — kill double-animation (root sway off, shader wind is the idle motion) + thin flowers
Operator: base flora too dense + "the waving/shader doesn't look great".
Diagnosis: EVERY Synty flora prop (both biomes) uses the Synty/Foliage
VERTEX-wind shader — the transform root-tilt sway has been double-animating
all flora since 1.5, and ground-flush carpet props (Flowers_Flat,
Grass_*_Plane) visibly lift their edges when tilted.

- AmbientMotionConfig.SwayEnabled -> false (code default + the serialized
  scene value): idle motion = the authored per-vertex shader wind (tips bend,
  bases planted). Knob kept for A/B; walk-through RUSTLE stays as the
  reactive layer the shader can't provide.
- AmbientMotionSystem: flat carpet props excluded from the flora cache
  entirely — no tilt even from rustle.
- Flower density thinned deterministically: Flowers_Flat keep 40%,
  Wildflowers/Sunflowers keep 50%, center (r<13) thinned harder (x0.6) —
  17/38 drifts off; play/build area reads clear, flowers become ring accents.

Console clean; sway/rustle knobs remain live-tunable in the scene.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 23:12:34 -07:00

50 lines
2.4 KiB
C#

using UnityEngine;
namespace ProjectM.Client
{
/// <summary>
/// Live-tunable knobs for <see cref="AmbientMotionSystem"/> — the Phase 1.5 "world alive" ambient layer
/// (per-biome drift particles + idle foliage sway + walk-through rustle). Mirrors the
/// <see cref="WorldAtmosphereConfig"/>/<see cref="DynamicLightConfig"/> bridge idiom: a MonoBehaviour in
/// the gameplay scene with a static <see cref="Instance"/> the client presentation system reads (falling
/// back to these same defaults when absent). Pure presentation — never touches the simulation.
/// </summary>
public sealed class AmbientMotionConfig : MonoBehaviour
{
public static AmbientMotionConfig Instance;
[Header("Master")]
public bool Enabled = true;
[Header("Biome drift particles (emitter follows the camera; sim space stays world)")]
public bool DriftEnabled = true;
[Min(0f)] public float DriftRate = 28f;
[Min(0.01f)] public float DriftSize = 0.09f;
public Color MeadowMoteColor = new Color(0.62f, 0.85f, 0.60f, 0.35f);
public Color AridDustColor = new Color(0.85f, 0.68f, 0.45f, 0.28f);
public Color CavernMoteColor = new Color(0.55f, 0.65f, 0.95f, 0.33f);
public Color BlightSporeColor = new Color(0.72f, 0.50f, 0.85f, 0.33f);
public Vector3 AridWind = new Vector3(2.2f, -0.15f, 0.5f);
[Header("Idle foliage sway (root tilt) — OFF by default since 1.5b: ALL Synty flora uses the Synty/Foliage")]
[Header("VERTEX-wind shader, so root tilt double-animates. Keep for A/B; rustle below stays the reactive layer.")]
public bool SwayEnabled = false;
[Min(1f)] public float SwayRadius = 30f;
[Min(0f)] public float SwayAmpDeg = 1.4f;
[Min(0.05f)] public float SwayHz = 0.8f;
[Header("Walk-through rustle (local player brushing flora)")]
public bool RustleEnabled = true;
[Min(0.2f)] public float RustleRadius = 1.7f;
[Min(0f)] public float RustleAmpDeg = 7f;
[Min(0.5f)] public float RustleHz = 9f;
[Min(0.2f)] public float RustleDecay = 2.5f;
void OnEnable() { Instance = this; }
void OnDisable() { if (Instance == this) Instance = null; }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void ResetStatics() { Instance = null; }
}
}