diff --git a/Assets/Scripts/Characters/PoisonZone.cs b/Assets/Scripts/Characters/PoisonZone.cs index 5a25857e4..a31f8ad88 100644 --- a/Assets/Scripts/Characters/PoisonZone.cs +++ b/Assets/Scripts/Characters/PoisonZone.cs @@ -18,8 +18,8 @@ public class PoisonZone : MonoBehaviour [Tooltip("Animation curve for ONE CYCLE of the looping Volume weight. X-axis (Time) from 0 to 1. Y-axis (Value) is the weight intensity (e.g., 0 to 1, where 1 is full effect defined by the curve values).")] public AnimationCurve loopingVolumeWeightCurve = new AnimationCurve( new Keyframe(0, 0), - new Keyframe(0.5f, 0.8f), // Example: peaks at 0.8 halfway through - new Keyframe(1, 0) // Example: returns to 0 at the end of the cycle + new Keyframe(0.5f, 0.8f), + new Keyframe(1, 0) ); [Tooltip("Duration of one full cycle of the looping animation, in seconds. Must be greater than 0.")] @@ -38,10 +38,10 @@ public class PoisonZone : MonoBehaviour private Player currentPlayerInZone; private float timeSinceLastDamage = 0f; private float timeSinceLastCough = 0f; - private bool playerCurrentlyInZone = false; + private bool playerCurrentlyInZone = false; // Ta flaga jest kluczowa dla logiki ponownego wejścia - private float currentLoopProgress = 0f; // Postęp w bieżącym cyklu pętli (0 to 1) - private float currentFadeProgress = 0f; // Postęp fade-in/fade-out (0 to 1), kontroluje ogólną intensywność pętli + private float currentLoopProgress = 0f; + private float currentFadeProgress = 0f; void Start() { @@ -57,63 +57,59 @@ public class PoisonZone : MonoBehaviour } else { - // Ustaw początkową wagę na 0 (ponieważ currentFadeProgress jest 0) poisonVolume.weight = 0f; poisonVolume.enabled = false; } - if (loopCycleDuration <= 0.001f) // Sprawdzenie, czy jest sensownie dodatni + if (loopCycleDuration <= 0.001f) { Debug.LogWarning("PoisonZone: Loop Cycle Duration should be greater than 0 for looping animation. Setting to 1s.", this); - loopCycleDuration = 1f; // Domyślna wartość, aby uniknąć dzielenia przez zero lub zbyt szybkich pętli + loopCycleDuration = 1f; } } void Update() { - // --- Volume Animation Logic --- if (poisonVolume != null) { - // 1. Update Fade Progress (kontroluje ogólną widoczność/intensywność pętli) float targetFadeProgress = playerCurrentlyInZone ? 1.0f : 0.0f; if (volumeFadeDuration > 0.001f) { float fadeStep = (1.0f / volumeFadeDuration) * Time.deltaTime; currentFadeProgress = Mathf.MoveTowards(currentFadeProgress, targetFadeProgress, fadeStep); } - else // Natychmiastowe włączenie/wyłączenie pętli (jeśli fade duration jest bliski 0) + else { currentFadeProgress = targetFadeProgress; } - // 2. Update Loop Progress (tylko jeśli efekt jest przynajmniej częściowo "widoczny" lub gracz jest w strefie) - // To zapewnia, że pętla rusza, gdy tylko zaczyna się fade-in. if (playerCurrentlyInZone || currentFadeProgress > 0.001f) { currentLoopProgress += Time.deltaTime / loopCycleDuration; - // Zapętlanie postępu: if (currentLoopProgress >= 1.0f) currentLoopProgress -= 1.0f; - // Lub użycie modulo dla płynniejszego przejścia, gdy Time.deltaTime jest duże: currentLoopProgress = currentLoopProgress % 1.0f; } - // 3. Calculate and Apply Volume Weight - // Wartość z krzywej pętli jest mnożona przez postęp fade'owania. float loopedWeightValue = loopingVolumeWeightCurve.Evaluate(currentLoopProgress); poisonVolume.weight = loopedWeightValue * currentFadeProgress; - // 4. Manage Volume Enabled State - // Włączamy Volume, jeśli jego waga jest wystarczająco duża, aby był widoczny. - bool shouldBeEnabled = poisonVolume.weight > 0.001f; + bool shouldBeEnabled; + if (currentFadeProgress > 0.001f) + { + shouldBeEnabled = true; + } + else + { + shouldBeEnabled = false; + } + if (poisonVolume.enabled != shouldBeEnabled) { poisonVolume.enabled = shouldBeEnabled; } } - // --- Damage and Sound Logic --- - if (playerCurrentlyInZone && currentPlayerInZone != null) + if (playerCurrentlyInZone && currentPlayerInZone != null) // Upewnij się, że currentPlayerInZone nie jest null { - // Zadawanie obrażeń timeSinceLastDamage += Time.deltaTime; if (timeSinceLastDamage >= damageInterval) { @@ -121,7 +117,6 @@ public class PoisonZone : MonoBehaviour timeSinceLastDamage = 0f; } - // Odtwarzanie dźwięku kaszlu if (coughSound != null && coughInterval > 0) { timeSinceLastCough += Time.deltaTime; @@ -139,22 +134,26 @@ public class PoisonZone : MonoBehaviour Player enteredPlayer = other.GetComponent(); if (enteredPlayer != null) { - if (currentPlayerInZone == null || currentPlayerInZone != enteredPlayer) + // Ta logika powinna poprawnie obsługiwać ponowne wejście tego samego gracza + // oraz wejście nowego gracza. + if (currentPlayerInZone != enteredPlayer || !playerCurrentlyInZone) { - currentPlayerInZone = enteredPlayer; - playerCurrentlyInZone = true; - timeSinceLastDamage = 0f; - timeSinceLastCough = 0f; // Reset timera kaszlu + // Jeśli to faktycznie nowy gracz LUB ten sam gracz, ale nie był 'aktywny' (playerCurrentlyInZone było false) + if (currentPlayerInZone != enteredPlayer) + { + currentPlayerInZone = enteredPlayer; // Zaktualizuj referencję tylko jeśli to inny gracz + } - // Opcjonalnie: zresetuj postęp pętli, aby zaczynała się od początku. - // currentLoopProgress = 0f; - // Jeśli chcesz, aby zaczynała się płynnie od początku przy każdym wejściu. + playerCurrentlyInZone = true; // Zawsze ustawiaj na true przy "aktywnym" wejściu + timeSinceLastDamage = 0f; + timeSinceLastCough = 0f; + currentLoopProgress = 0f; // Resetuj pętlę animacji Volume if (coughSound != null) { - PlayCoughSound(); // Kaszel od razu przy wejściu + PlayCoughSound(); } - //Debug.Log(enteredPlayer.name + " entered poison zone: " + gameObject.name); + // Debug.Log($"{enteredPlayer.name} ENTERED/RE-ENTERED zone. playerCurrentlyInZone: {playerCurrentlyInZone}"); } } } @@ -162,11 +161,12 @@ public class PoisonZone : MonoBehaviour void OnTriggerExit(Collider other) { Player exitedPlayer = other.GetComponent(); - if (exitedPlayer != null && exitedPlayer == currentPlayerInZone) + // Sprawdzamy, czy to TEN gracz, który był aktywnie śledzony w strefie i właśnie opuszcza. + if (exitedPlayer != null && exitedPlayer == currentPlayerInZone && playerCurrentlyInZone) { - playerCurrentlyInZone = false; - // Nie zerujemy currentPlayerInZone tutaj, currentFadeProgress zajmie się wygaszeniem efektu. - //Debug.Log(exitedPlayer.name + " exited poison zone: " + gameObject.name); + playerCurrentlyInZone = false; // Oznacz, że gracz (ten konkretny) już nie jest aktywnie w strefie + // Debug.Log($"{exitedPlayer.name} EXITED zone. playerCurrentlyInZone: {playerCurrentlyInZone}"); + // Nie zerujemy currentPlayerInZone, aby OnTriggerEnter mogło poprawnie wykryć powrót tego samego gracza. } } @@ -177,7 +177,14 @@ public class PoisonZone : MonoBehaviour var healthController = currentPlayerInZone.ThirdPersonController; if (healthController != null && !healthController.isDead) { + // Ta linia jest kluczowa dla pomijania animacji hita. + // Zakłada, że masz zmodyfikowany vDamage.cs (z polem ignoreHitEffects) + // oraz odpowiednie warunki w Player.cs i vHealthController.cs. vDamage damageInstance = new vDamage(damageAmount, true); + // Jeśli vDamage(int, bool) nie istnieje, a vDamage.cs jest zmodyfikowane: + // vDamage damageInstance = new vDamage(damageAmount); + // damageInstance.ignoreHitEffects = true; + healthController.TakeDamage(damageInstance); } } diff --git a/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg b/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg new file mode 100644 index 000000000..1987044b5 Binary files /dev/null and b/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg differ diff --git a/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg.meta b/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg.meta new file mode 100644 index 000000000..3b53616f7 --- /dev/null +++ b/Assets/ThirdParty/Invector-3rdPersonController/Melee Combat/Audio/Player_cough.ogg.meta @@ -0,0 +1,41 @@ +fileFormatVersion: 2 +guid: 08f8ddcc9fadca44b88de3155aa75c5e +AudioImporter: + externalObjects: {} + serializedVersion: 8 + defaultSettings: + serializedVersion: 2 + loadType: 0 + sampleRateSetting: 0 + sampleRateOverride: 44100 + compressionFormat: 0 + quality: 1 + conversionMode: 0 + preloadAudioData: 0 + platformSettingOverrides: + 4: + serializedVersion: 2 + loadType: 0 + sampleRateSetting: 0 + sampleRateOverride: 44100 + compressionFormat: 0 + quality: 1 + conversionMode: 0 + preloadAudioData: 0 + 7: + serializedVersion: 2 + loadType: 0 + sampleRateSetting: 0 + sampleRateOverride: 44100 + compressionFormat: 1 + quality: 1 + conversionMode: 0 + preloadAudioData: 0 + forceToMono: 0 + normalize: 1 + loadInBackground: 0 + ambisonic: 0 + 3D: 1 + userData: + assetBundleName: + assetBundleVariant: