// --- PEŁNY I POPRAWIONY SKRYPT FOGZONE.CS --- using System.Collections; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif /// /// Zarządza lokalną strefą mgły URP. Zmienia globalne ustawienia RenderSettings /// z płynnym przejściem. Działa w trybie gry (triggery, eventy) oraz w edytorze (podgląd). /// [ExecuteAlways] [RequireComponent(typeof(Collider))] public class FogZone : MonoBehaviour { [Header("Ustawienia Docelowe Mgły (Wewnątrz Strefy)")] public Color targetFogColor = new Color(0.5f, 0.5f, 0.5f); public FogMode targetFogMode = FogMode.Exponential; [Range(0f, 1f)] public float targetFogDensity = 0.02f; public float targetFogStartDistance = 0f; public float targetFogEndDistance = 300f; [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 (zazwyczaj gracza), który ma aktywować strefę.")] public string playerTag = "Player"; [Header("Ustawienia Edytora")] [Tooltip("Włącza podgląd mgły w edytorze, gdy kamera Scene View wejdzie do strefy.")] public bool enableEditorPreview = true; // Statyczne, by zapewnić, że tylko jedna zmiana mgły dzieje się naraz w całej grze private static Coroutine s_transitionCoroutine; private static MonoBehaviour s_coroutineRunner; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void InitializeOnLoad() { s_transitionCoroutine = null; s_coroutineRunner = null; } // --- NOWA LOGIKA - SPRAWDZENIE NA STARCIE GRY --- /// /// Sprawdza na starcie gry, czy gracz już znajduje się w strefie. /// Jeśli tak, aktywuje mgłę natychmiast. /// private void Start() { // Upewniamy się, że ten kod działa tylko w trybie gry, a nie w edytorze if (!Application.isPlaying) { return; } // Znajdź obiekt gracza na scenie za pomocą tagu GameObject playerObject = GameObject.FindWithTag(playerTag); if (playerObject == null) { // Jeśli nie ma gracza na scenie (lub ma zły tag), nic nie robimy return; } // Pobierz collider tej strefy mgły Collider zoneCollider = GetComponent(); // Sprawdź, czy pozycja gracza znajduje się wewnątrz granic collidera tej strefy if (zoneCollider.bounds.Contains(playerObject.transform.position)) { Debug.Log($"Gracz '{playerObject.name}' rozpoczął grę wewnątrz strefy '{this.name}'. Ustawiam mgłę natychmiast.", this); // Używamy małej sztuczki: tymczasowo ustawiamy czas przejścia na 0, // aby mgła pojawiła się od razu, a nie płynnie. float originalDuration = transitionDuration; transitionDuration = 0f; // Uruchom logikę wejścia do strefy StartTransition(true); // Przywróć oryginalny czas przejścia, aby późniejsze wejścia/wyjścia // działały z normalną, płynną animacją. transitionDuration = originalDuration; } } // --- LOGIKA TRYBU GRY (BEZ ZMIAN) --- 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); } } // --- PUBLICZNE METODY DLA EVENTÓW (CUTSCENY) --- public void ActivateZoneFogFromEvent() { if (!Application.isPlaying) return; StartTransition(true); } public void RevertToDefaultFogFromEvent() { if (!Application.isPlaying) return; StartTransition(false); } // --- GŁÓWNA LOGIKA PRZEJŚCIA (BEZ ZMIAN) --- private void StartTransition(bool toZoneSettings) { if (s_transitionCoroutine != null && s_coroutineRunner != null) { s_coroutineRunner.StopCoroutine(s_transitionCoroutine); } s_coroutineRunner = this; s_transitionCoroutine = StartCoroutine(TransitionFog(toZoneSettings)); } private IEnumerator TransitionFog(bool toZoneSettings) { Color startColor = RenderSettings.fogColor; float startDensity = RenderSettings.fogDensity; float startLinearStart = RenderSettings.fogStartDistance; float startLinearEnd = RenderSettings.fogEndDistance; Color endColor; FogMode endMode; float endDensity; float endLinearStart; float endLinearEnd; if (toZoneSettings) { endColor = targetFogColor; endMode = targetFogMode; endDensity = targetFogDensity; endLinearStart = targetFogStartDistance; endLinearEnd = targetFogEndDistance; RenderSettings.fogMode = endMode; } else { var defaults = FogDefaultSettings.Instance; if (defaults == null) { Debug.LogError("Nie znaleziono FogDefaultSettings w scenie!", this); yield break; } endColor = defaults.fogColor; endMode = defaults.fogMode; endDensity = defaults.fogDensity; endLinearStart = defaults.fogStartDistance; endLinearEnd = defaults.fogEndDistance; } RenderSettings.fog = true; float elapsed = 0f; while (elapsed < transitionDuration) { // Jeśli czas przejścia jest 0 (jak w naszym przypadku na starcie), 't' od razu będzie 1 float t = (transitionDuration > 0) ? Mathf.Clamp01(elapsed / transitionDuration) : 1f; RenderSettings.fogColor = Color.Lerp(startColor, endColor, t); RenderSettings.fogDensity = Mathf.Lerp(startDensity, endDensity, t); RenderSettings.fogStartDistance = Mathf.Lerp(startLinearStart, endLinearStart, t); RenderSettings.fogEndDistance = Mathf.Lerp(startLinearEnd, endLinearEnd, t); elapsed += Time.deltaTime; yield return null; } // Upewniamy się, że na końcu są dokładnie docelowe wartości RenderSettings.fogColor = endColor; RenderSettings.fogDensity = endDensity; RenderSettings.fogStartDistance = endLinearStart; RenderSettings.fogEndDistance = endLinearEnd; if (!toZoneSettings && FogDefaultSettings.Instance != null) { RenderSettings.fogMode = FogDefaultSettings.Instance.fogMode; RenderSettings.fog = FogDefaultSettings.Instance.fogEnabled; } s_transitionCoroutine = null; s_coroutineRunner = null; } // --- LOGIKA TYLKO DLA EDYTORA UNITY (BEZ ZMIAN) --- #if UNITY_EDITOR private static bool s_editorSettingsSaved = false; private static FogZone s_editorActiveZone = null; private static bool s_prevFogEnabled; private static Color s_prevFogColor; private static FogMode s_prevFogMode; private static float s_prevFogDensity; private static float s_prevFogStartDist; private static float s_prevFogEndDist; private void OnEnable() { var col = GetComponent(); if (col != null) col.isTrigger = true; if (!Application.isPlaying) { EditorApplication.update += EditorUpdate; } } private void OnDisable() { if (!Application.isPlaying) { EditorApplication.update -= EditorUpdate; if (s_editorActiveZone == this) { RestoreEditorSettings(); s_editorActiveZone = null; } } } private void EditorUpdate() { if (Application.isPlaying) return; if (!enableEditorPreview) { if (s_editorActiveZone == this) { RestoreEditorSettings(); s_editorActiveZone = null; } return; } var sceneView = SceneView.lastActiveSceneView; if (sceneView == null || sceneView.camera == null) return; var zoneCollider = GetComponent(); if (zoneCollider == null) return; bool isCameraInside = zoneCollider.bounds.Contains(sceneView.camera.transform.position); if (isCameraInside) { if (s_editorActiveZone != this) { if (s_editorActiveZone == null) { SaveEditorSettings(); } s_editorActiveZone = this; ApplyZoneSettingsDirectly(); } } else { if (s_editorActiveZone == this) { RestoreEditorSettings(); s_editorActiveZone = null; } } } private void OnValidate() { if (!Application.isPlaying && s_editorActiveZone == this) { ApplyZoneSettingsDirectly(); } } private static void SaveEditorSettings() { if (s_editorSettingsSaved) return; s_prevFogEnabled = RenderSettings.fog; s_prevFogColor = RenderSettings.fogColor; s_prevFogMode = RenderSettings.fogMode; s_prevFogDensity = RenderSettings.fogDensity; s_prevFogStartDist = RenderSettings.fogStartDistance; s_prevFogEndDist = RenderSettings.fogEndDistance; s_editorSettingsSaved = true; } private void ApplyZoneSettingsDirectly() { RenderSettings.fog = true; RenderSettings.fogMode = targetFogMode; RenderSettings.fogColor = targetFogColor; RenderSettings.fogDensity = targetFogDensity; RenderSettings.fogStartDistance = targetFogStartDistance; RenderSettings.fogEndDistance = targetFogEndDistance; SceneView.RepaintAll(); } private static void RestoreEditorSettings() { if (!s_editorSettingsSaved) return; RenderSettings.fog = s_prevFogEnabled; RenderSettings.fogColor = s_prevFogColor; RenderSettings.fogMode = s_prevFogMode; RenderSettings.fogDensity = s_prevFogDensity; RenderSettings.fogStartDistance = s_prevFogStartDist; RenderSettings.fogEndDistance = s_prevFogEndDist; s_editorSettingsSaved = false; SceneView.RepaintAll(); } #endif }