diff --git a/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs b/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs
new file mode 100644
index 0000000..d743164
--- /dev/null
+++ b/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs
@@ -0,0 +1,164 @@
+using System.Collections;
+using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEngine.Rendering.Universal;
+
+///
+/// Builds the environment reflection from the current Skybox in memory (renders
+/// the sky into a cubemap and assigns it as the Custom reflection), so
+/// smooth/metallic materials reflect the sky WITHOUT a baked LightingData.asset.
+/// Runs in Edit and Play mode ([ExecuteAlways]); drop it on one object per scene
+/// (or a prefab that lives in every scene) and you never have to assign a foreign
+/// LightingData again — also works for runtime-loaded / procedural scenes.
+///
+/// Why a rendered cubemap and not :
+/// in this project UpdateEnvironment does NOT produce a valid skybox reflection
+/// probe (a mirror stays black), so
+/// had nothing to scale. Rendering the sky into a Custom reflection cubemap gives a
+/// real reflection that intensity can actually drive.
+///
+/// The skybox AMBIENT probe still comes from UpdateEnvironment — but it only convolves a
+/// non-zero probe once the sky has actually been rendered this session. Straight after a
+/// domain reload / scene load / play-start the sky hasn't rendered yet, so the probe is
+/// ZERO and the Environment intensity multiplier has nothing to scale ("doesn't take
+/// effect" until a manual re-enable). Fix: do one synchronous full-screen sky render to
+/// "warm" the sky right before UpdateEnvironment — deterministic, no waiting on renders.
+/// (RenderToCubemap does NOT warm the ambient path; a normal Camera.Render does.)
+///
+[ExecuteAlways]
+[DisallowMultipleComponent]
+public class SkyboxEnvironmentUpdater : MonoBehaviour
+{
+ [Range(0f, 4f)]
+ public float environmentLightingIntensity = 1;
+
+ [Header("Reflections")]
+
+ [Tooltip("Resolution of the generated sky reflection cubemap (power of two).")]
+ public int reflectionResolution = 128;
+
+ [Tooltip("How strongly the sky reflection tints reflective/metallic surfaces. 1 = neutral; the Lighting window slider caps at 1, but higher values (via this field) over-drive the reflection for a glossier metal look. Only applied while Force Skybox Reflections is on.")]
+ [Range(0f, 4f)]
+ public float reflectionIntensity = 1f;
+
+ [Tooltip("Optional: render THIS sky material into the reflection cubemap instead of the scene's global Skybox. Leave empty to use RenderSettings.skybox. Only affects the reflection — the visible scene skybox is unchanged.")]
+ public Material reflectionSkyOverride;
+
+ [System.NonSerialized] Cubemap _reflectionCube;
+
+ void OnDisable()
+ {
+#if UNITY_EDITOR
+ UnityEditor.EditorApplication.delayCall -= Apply;
+#endif
+ if (!_reflectionCube)
+ return;
+
+ if (RenderSettings.customReflectionTexture == _reflectionCube)
+ RenderSettings.customReflectionTexture = null;
+
+ DestroyImmediate(_reflectionCube);
+
+ _reflectionCube = null;
+ }
+
+ void OnValidate()
+ {
+ if (this && isActiveAndEnabled)
+ OnEnable();
+ else
+ OnDisable();
+ }
+
+ void OnEnable()
+ {
+ if (!RenderSettings.skybox && !reflectionSkyOverride)
+ return;
+
+#if UNITY_EDITOR
+ if (!Application.isPlaying)
+ {
+ UnityEditor.EditorApplication.delayCall -= Apply;
+ UnityEditor.EditorApplication.delayCall += Apply;
+ return;
+ }
+#endif
+ StartCoroutine(ApplyNextFrame());
+ }
+
+ IEnumerator ApplyNextFrame()
+ {
+ yield return null;
+ Apply();
+ }
+
+ void Apply()
+ {
+ if (!this || !isActiveAndEnabled)
+ return;
+
+ if (!RenderSettings.skybox && !reflectionSkyOverride)
+ return;
+
+ RenderSettings.ambientIntensity = environmentLightingIntensity;
+
+ var camGo = new GameObject("__SkyboxEnvCam") { hideFlags = HideFlags.HideAndDontSave };
+ try
+ {
+ var cam = camGo.AddComponent();
+ cam.enabled = false;
+ cam.cullingMask = 0;
+ cam.clearFlags = CameraClearFlags.Skybox;
+ cam.cameraType = CameraType.Reflection;
+
+ var camData = camGo.AddComponent();
+ camData.renderPostProcessing = false;
+ camData.requiresDepthTexture = false;
+ camData.requiresColorTexture = false;
+ camData.renderShadows = false;
+
+ if (reflectionSkyOverride)
+ camGo.AddComponent().material = reflectionSkyOverride;
+
+ camGo.transform.position = transform.position;
+
+ var rt = RenderTexture.GetTemporary(64, 64, 16);
+ cam.targetTexture = rt;
+ cam.Render();
+ cam.targetTexture = null;
+ RenderTexture.ReleaseTemporary(rt);
+
+ EnsureReflectionCubemap();
+ cam.RenderToCubemap(_reflectionCube);
+ }
+ finally
+ {
+ DestroyImmediate(camGo);
+ }
+
+ RenderSettings.defaultReflectionMode = DefaultReflectionMode.Custom;
+ RenderSettings.customReflectionTexture = _reflectionCube;
+ RenderSettings.reflectionIntensity = reflectionIntensity;
+
+ RenderSettings.ambientMode = AmbientMode.Skybox;
+ DynamicGI.UpdateEnvironment();
+ }
+
+ void EnsureReflectionCubemap()
+ {
+ int size = Mathf.Max(16, reflectionResolution);
+
+ if (!_reflectionCube || _reflectionCube.width != size)
+ {
+ if (_reflectionCube)
+ {
+ DestroyImmediate(_reflectionCube);
+ }
+
+ _reflectionCube = new Cubemap(size, TextureFormat.RGBA32, true)
+ {
+ name = "SkyboxReflection (generated)"
+ };
+ }
+ }
+}
diff --git a/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs.meta b/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs.meta
new file mode 100644
index 0000000..287330d
--- /dev/null
+++ b/Assets/Scripts/Components/SkyboxEnvironmentUpdater.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 8ad6962cd13b2914a82ab60384f37a3b
\ No newline at end of file