// --- WERSJA 8 - FINALNA POPRAWIONA: DirectionalLightZone.cs (Wydajny + Pełny Podgląd w Edytorze) --- using System.Collections; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif [ExecuteAlways] [RequireComponent(typeof(Collider))] public class DirectionalLightZone : MonoBehaviour { [Header("Ustawienia Edytora")] [Tooltip("Włącza podgląd w edytorze, gdy kamera Scene View wejdzie do strefy.")] public bool enableEditorPreview = true; [Header("Ustawienia Główne")] public Light directionalLight; [Tooltip("Czas w sekundach, w jakim światło będzie płynnie wygaszane/rozjaśniane.")] public float transitionDuration = 2.0f; [Tooltip("Tag obiektu gracza.")] public string playerTag = "Player"; private static float s_defaultIntensity; private static bool s_defaultIntensityStored = false; private static Coroutine s_activeTransition; private static MonoBehaviour s_coroutineRunner; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetStatics() { s_defaultIntensityStored = false; s_activeTransition = null; s_coroutineRunner = null; #if UNITY_EDITOR s_editorActiveZone = null; s_editorSettingsSaved = false; #endif } private void Awake() { GetComponent().isTrigger = true; if (directionalLight == null) { this.enabled = false; return; } if (Application.isPlaying && !s_defaultIntensityStored) { s_defaultIntensity = directionalLight.intensity; s_defaultIntensityStored = true; } } private void OnTriggerEnter(Collider other) { if (Application.isPlaying && other.CompareTag(playerTag)) StartTransition(false); } private void OnTriggerExit(Collider other) { if (Application.isPlaying && other.CompareTag(playerTag)) StartTransition(true); } private void StartTransition(bool fadeIn) { if (s_activeTransition != null && s_coroutineRunner != null) s_coroutineRunner.StopCoroutine(s_activeTransition); s_coroutineRunner = this; s_activeTransition = StartCoroutine(TransitionLight(fadeIn)); } private IEnumerator TransitionLight(bool fadeIn) { float startIntensity = directionalLight.intensity; float targetIntensity = fadeIn ? s_defaultIntensity : 0f; if (fadeIn && !directionalLight.enabled) directionalLight.enabled = true; float elapsed = 0f; while (elapsed < transitionDuration) { float t = (transitionDuration > 0) ? elapsed / transitionDuration : 1f; directionalLight.intensity = Mathf.Lerp(startIntensity, targetIntensity, t); elapsed += Time.deltaTime; yield return null; } directionalLight.intensity = targetIntensity; if (!fadeIn) directionalLight.enabled = false; s_activeTransition = null; } #if UNITY_EDITOR private static DirectionalLightZone s_editorActiveZone = null; private static float s_editorOriginalIntensity; private static bool s_editorOriginalEnabled; private static bool s_editorSettingsSaved = false; private void OnEnable() { EditorApplication.update += EditorUpdate; if (!Application.isPlaying) EditorUpdate(); } private void OnDisable() { EditorApplication.update -= EditorUpdate; if (!Application.isPlaying && s_editorActiveZone == this) { RestoreEditorSettings(); } } private void EditorUpdate() { if (Application.isPlaying) return; if (!enableEditorPreview) { if (s_editorActiveZone == this) RestoreEditorSettings(); return; } if (directionalLight == null) return; var sceneView = SceneView.lastActiveSceneView; if (sceneView == null || sceneView.camera == null) return; bool isCameraInside = GetComponent().bounds.Contains(sceneView.camera.transform.position); if (isCameraInside) { if (s_editorActiveZone != this) { if (!s_editorSettingsSaved) SaveEditorSettings(); s_editorActiveZone = this; } directionalLight.enabled = false; SceneView.RepaintAll(); } else { if (s_editorActiveZone == this) RestoreEditorSettings(); } } private void SaveEditorSettings() { s_editorOriginalIntensity = directionalLight.intensity; s_editorOriginalEnabled = directionalLight.enabled; s_editorSettingsSaved = true; } private void RestoreEditorSettings() { if (!s_editorSettingsSaved) return; directionalLight.intensity = s_editorOriginalIntensity; directionalLight.enabled = s_editorOriginalEnabled; s_editorSettingsSaved = false; s_editorActiveZone = null; SceneView.RepaintAll(); } #endif }