// --- WERSJA 8 - FINALNA POPRAWIONA: HeightFogZone.cs (Wydajny + Pełny Podgląd w Edytorze) --- using System.Collections; using UnityEngine; using AtmosphericHeightFog; #if UNITY_EDITOR using UnityEditor; #endif [ExecuteAlways] [RequireComponent(typeof(Collider))] public class HeightFogZone : MonoBehaviour { [Header("Ustawienia Edytora")] [Tooltip("Włącza podgląd mgły w edytorze, gdy kamera Scene View wejdzie do strefy.")] public bool enableEditorPreview = true; [Header("Docelowe Ustawienia Mgły")] [Range(0f, 1f)] public float targetFogIntensity = 0.5f; [ColorUsage(true, true)] public Color targetFogColorStart = new Color(0.5f, 0.75f, 1f, 1f); [ColorUsage(true, true)] public Color targetFogColorEnd = new Color(0.75f, 1.25f, 1f, 1f); [Range(0f, 1f)] public float targetFogColorDuo = 0f; public float targetFogDistanceStart = -50f; public float targetFogDistanceEnd = 150f; [Range(1f, 8f)] public float targetFogDistanceFalloff = 2f; [Range(0f, 1f)] public float targetDirectionalIntensity = 0.5f; [Header("Ustawienia Zachowania")] [Tooltip("Czas w sekundach, w jakim mgła będzie płynnie przechodzić do nowych ustawień.")] public float transitionDuration = 2.0f; [Tooltip("Tag obiektu gracza.")] public string playerTag = "Player"; private static HeightFogGlobal s_fogGlobalInstance; private static DefaultFogValues s_defaultValues; private static bool s_defaultsStored = false; private static Coroutine s_activeTransition; private static MonoBehaviour s_coroutineRunner; private struct DefaultFogValues { public float fogIntensity; public Color fogColorStart; public Color fogColorEnd; public float fogColorDuo; public float fogDistanceStart; public float fogDistanceEnd; public float fogDistanceFalloff; public float directionalIntensity; } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetStatics() { s_fogGlobalInstance = null; s_defaultsStored = false; s_activeTransition = null; s_coroutineRunner = null; #if UNITY_EDITOR s_editorActiveZone = null; s_editorSettingsSaved = false; #endif } private void Awake() { GetComponent().isTrigger = true; if (s_fogGlobalInstance == null) s_fogGlobalInstance = FindFirstObjectByType(); if (Application.isPlaying && !s_defaultsStored && s_fogGlobalInstance != null) { StoreDefaultValues(); } } private void OnTriggerEnter(Collider other) { if (Application.isPlaying && other.CompareTag(playerTag)) StartTransition(true); } private void OnTriggerExit(Collider other) { if (Application.isPlaying && other.CompareTag(playerTag)) StartTransition(false); } private void StartTransition(bool toZoneSettings) { if (s_fogGlobalInstance == null || !s_defaultsStored) return; if (s_activeTransition != null && s_coroutineRunner != null) s_coroutineRunner.StopCoroutine(s_activeTransition); s_coroutineRunner = this; s_activeTransition = StartCoroutine(TransitionFog(toZoneSettings)); } private IEnumerator TransitionFog(bool toZoneSettings) { DefaultFogValues startValues = new DefaultFogValues { fogIntensity = s_fogGlobalInstance.fogIntensity, fogColorStart = s_fogGlobalInstance.fogColorStart, fogColorEnd = s_fogGlobalInstance.fogColorEnd, fogColorDuo = s_fogGlobalInstance.fogColorDuo, fogDistanceStart = s_fogGlobalInstance.fogDistanceStart, fogDistanceEnd = s_fogGlobalInstance.fogDistanceEnd, fogDistanceFalloff = s_fogGlobalInstance.fogDistanceFalloff, directionalIntensity = s_fogGlobalInstance.directionalIntensity }; DefaultFogValues targetValues = toZoneSettings ? new DefaultFogValues { fogIntensity = targetFogIntensity, fogColorStart = targetFogColorStart, fogColorEnd = targetFogColorEnd, fogColorDuo = targetFogColorDuo, fogDistanceStart = targetFogDistanceStart, fogDistanceEnd = targetFogDistanceEnd, fogDistanceFalloff = targetFogDistanceFalloff, directionalIntensity = targetDirectionalIntensity } : s_defaultValues; float elapsed = 0f; while (elapsed < transitionDuration) { float t = (transitionDuration > 0) ? elapsed / transitionDuration : 1f; ApplyLerpedSettings(startValues, targetValues, t); elapsed += Time.deltaTime; yield return null; } ApplyLerpedSettings(startValues, targetValues, 1f); s_activeTransition = null; } private void StoreDefaultValues() { /* Implementacja bez zmian */ s_defaultValues = new DefaultFogValues { fogIntensity = s_fogGlobalInstance.fogIntensity, fogColorStart = s_fogGlobalInstance.fogColorStart, fogColorEnd = s_fogGlobalInstance.fogColorEnd, fogColorDuo = s_fogGlobalInstance.fogColorDuo, fogDistanceStart = s_fogGlobalInstance.fogDistanceStart, fogDistanceEnd = s_fogGlobalInstance.fogDistanceEnd, fogDistanceFalloff = s_fogGlobalInstance.fogDistanceFalloff, directionalIntensity = s_fogGlobalInstance.directionalIntensity }; s_defaultsStored = true; } private void ApplyLerpedSettings(DefaultFogValues start, DefaultFogValues end, float t) { /* Implementacja bez zmian */ s_fogGlobalInstance.fogIntensity = Mathf.Lerp(start.fogIntensity, end.fogIntensity, t); s_fogGlobalInstance.fogColorStart = Color.Lerp(start.fogColorStart, end.fogColorStart, t); s_fogGlobalInstance.fogColorEnd = Color.Lerp(start.fogColorEnd, end.fogColorEnd, t); s_fogGlobalInstance.fogColorDuo = Mathf.Lerp(start.fogColorDuo, end.fogColorDuo, t); s_fogGlobalInstance.fogDistanceStart = Mathf.Lerp(start.fogDistanceStart, end.fogDistanceStart, t); s_fogGlobalInstance.fogDistanceEnd = Mathf.Lerp(start.fogDistanceEnd, end.fogDistanceEnd, t); s_fogGlobalInstance.fogDistanceFalloff = Mathf.Lerp(start.fogDistanceFalloff, end.fogDistanceFalloff, t); s_fogGlobalInstance.directionalIntensity = Mathf.Lerp(start.directionalIntensity, end.directionalIntensity, t); } #if UNITY_EDITOR private static HeightFogZone s_editorActiveZone = null; private static DefaultFogValues s_editorOriginalValues; private static bool s_editorSettingsSaved = false; private void OnEnable() { EditorApplication.update += EditorUpdate; // Natychmiastowa reakcja na włączenie komponentu if (!Application.isPlaying) EditorUpdate(); } private void OnDisable() { EditorApplication.update -= EditorUpdate; // Natychmiastowe przywrócenie ustawień po wyłączeniu komponentu if (!Application.isPlaying && s_editorActiveZone == this) { RestoreEditorSettings(); } } private void EditorUpdate() { if (Application.isPlaying) return; if (!enableEditorPreview) { if (s_editorActiveZone == this) RestoreEditorSettings(); return; } if (s_fogGlobalInstance == null) s_fogGlobalInstance = FindFirstObjectByType(); if (s_fogGlobalInstance == 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; } ApplyZoneSettingsDirectly(); } else { if (s_editorActiveZone == this) RestoreEditorSettings(); } } private void OnValidate() { if (!Application.isPlaying) EditorApplication.QueuePlayerLoopUpdate(); } private void SaveEditorSettings() { s_editorOriginalValues = new DefaultFogValues { /* ... (kopiowanie wartości) ... */ fogIntensity = s_fogGlobalInstance.fogIntensity, fogColorStart = s_fogGlobalInstance.fogColorStart, fogColorEnd = s_fogGlobalInstance.fogColorEnd, fogColorDuo = s_fogGlobalInstance.fogColorDuo, fogDistanceStart = s_fogGlobalInstance.fogDistanceStart, fogDistanceEnd = s_fogGlobalInstance.fogDistanceEnd, fogDistanceFalloff = s_fogGlobalInstance.fogDistanceFalloff, directionalIntensity = s_fogGlobalInstance.directionalIntensity }; s_editorSettingsSaved = true; } private void RestoreEditorSettings() { if (!s_editorSettingsSaved) return; ApplyLerpedSettings(s_editorOriginalValues, s_editorOriginalValues, 1f); s_editorSettingsSaved = false; s_editorActiveZone = null; SceneView.RepaintAll(); } private void ApplyZoneSettingsDirectly() { // Ta metoda jest taka sama jak w poprzedniej wersji s_fogGlobalInstance.fogIntensity = targetFogIntensity; s_fogGlobalInstance.fogColorStart = targetFogColorStart; s_fogGlobalInstance.fogColorEnd = targetFogColorEnd; s_fogGlobalInstance.fogColorDuo = targetFogColorDuo; s_fogGlobalInstance.fogDistanceStart = targetFogDistanceStart; s_fogGlobalInstance.fogDistanceEnd = targetFogDistanceEnd; s_fogGlobalInstance.fogDistanceFalloff = targetFogDistanceFalloff; s_fogGlobalInstance.directionalIntensity = targetDirectionalIntensity; SceneView.RepaintAll(); } #endif }