Poison Zone WIP
This commit is contained in:
@@ -864,6 +864,52 @@ namespace Beyond
|
||||
ThirdPersonController._rigidbody.MovePosition(t.position);
|
||||
ThirdPersonController._rigidbody.MoveRotation(t.rotation);
|
||||
}
|
||||
|
||||
public void PlaySingleSound(AudioClip clipToPlay, bool destroyAfterPlaying = true)
|
||||
{
|
||||
// Opcjonalne opóŸnienie na starcie poziomu, aby unikn¹æ "spamowania" dŸwiêkami
|
||||
if (Time.timeSinceLevelLoad < 0.5f && clipToPlay != null)
|
||||
{
|
||||
// Mo¿esz chcieæ to odkomentowaæ, jeœli dŸwiêki na starcie s¹ problemem
|
||||
// return;
|
||||
}
|
||||
|
||||
if (this.audioSource == null) // this.audioSource to pole GameObject (prefab) w Player.cs
|
||||
{
|
||||
Debug.LogWarning("Player's 'audioSource' (GameObject prefab) is not assigned in Inspector. Cannot play sound: " + (clipToPlay ? clipToPlay.name : "Unknown clip"));
|
||||
return;
|
||||
}
|
||||
if (clipToPlay == null)
|
||||
{
|
||||
Debug.LogWarning("Attempted to play a null AudioClip.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Instancjonowanie prefabu dŸwiêkowego
|
||||
// Upewnij siê, ¿e prefab 'audioSource' ma komponent AudioSource
|
||||
GameObject audioObjectInstance = Instantiate(this.audioSource, transform.position, transform.rotation);
|
||||
AudioSource sourceComponent = audioObjectInstance.GetComponent<AudioSource>();
|
||||
|
||||
if (sourceComponent != null)
|
||||
{
|
||||
// PlayOneShot jest dobre dla efektów, nie przerywa innych dŸwiêków na tym samym source,
|
||||
// jeœli s¹ one odtwarzane przez .Play() i nie u¿ywaj¹ tego samego kana³u.
|
||||
sourceComponent.PlayOneShot(clipToPlay);
|
||||
|
||||
if (destroyAfterPlaying)
|
||||
{
|
||||
// Niszczymy obiekt GameObject zawieraj¹cy AudioSource po zakoñczeniu odtwarzania klipu.
|
||||
// Dodajemy ma³y bufor czasowy, aby upewniæ siê, ¿e dŸwiêk zd¹¿y siê odtworzyæ w ca³oœci.
|
||||
Destroy(audioObjectInstance, clipToPlay.length + 0.1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("The instantiated 'audioSource' prefab (from Player.cs) does not have an AudioSource component. Destroying instance.");
|
||||
Destroy(audioObjectInstance); // Posprz¹taj, jeœli coœ posz³o nie tak
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
|
||||
193
Assets/Scripts/Characters/PoisonZone.cs
Normal file
193
Assets/Scripts/Characters/PoisonZone.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering; // Potrzebne dla Volume
|
||||
using Beyond; // Dla dostêpu do Twojej klasy Player
|
||||
using Invector; // Dla vDamage
|
||||
|
||||
public class PoisonZone : MonoBehaviour
|
||||
{
|
||||
[Header("Damage Settings")]
|
||||
[Tooltip("Amount of damage dealt at each interval.")]
|
||||
public int damageAmount = 5;
|
||||
[Tooltip("Time in seconds between each damage tick.")]
|
||||
public float damageInterval = 1.0f;
|
||||
|
||||
[Header("Volume Animation Settings")]
|
||||
[Tooltip("Reference to the Volume component to animate.")]
|
||||
public Volume poisonVolume;
|
||||
|
||||
[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
|
||||
);
|
||||
|
||||
[Tooltip("Duration of one full cycle of the looping animation, in seconds. Must be greater than 0.")]
|
||||
public float loopCycleDuration = 2.0f;
|
||||
|
||||
[Tooltip("Duration of the fade-in/fade-out effect for the looping animation, in seconds. Set to 0 for instant on/off of the loop.")]
|
||||
public float volumeFadeDuration = 1.0f;
|
||||
|
||||
|
||||
[Header("Sound Settings")]
|
||||
[Tooltip("Coughing sound effect to play.")]
|
||||
public AudioClip coughSound;
|
||||
[Tooltip("Interval in seconds for repeating the cough sound while player is in the zone. Set to 0 for no repeat (only on enter).")]
|
||||
public float coughInterval = 4.0f;
|
||||
|
||||
private Player currentPlayerInZone;
|
||||
private float timeSinceLastDamage = 0f;
|
||||
private float timeSinceLastCough = 0f;
|
||||
private bool playerCurrentlyInZone = false;
|
||||
|
||||
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
|
||||
|
||||
void Start()
|
||||
{
|
||||
Collider col = GetComponent<Collider>();
|
||||
if (col == null || !col.isTrigger)
|
||||
{
|
||||
Debug.LogWarning($"PoisonZone: Collider not found or not set to 'Is Trigger' on GameObject: {gameObject.name}", this);
|
||||
}
|
||||
|
||||
if (poisonVolume == null)
|
||||
{
|
||||
Debug.LogWarning($"PoisonZone: No Volume assigned in Inspector. Post-processing effects will not be animated for {gameObject.name}", this);
|
||||
}
|
||||
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
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (poisonVolume.enabled != shouldBeEnabled)
|
||||
{
|
||||
poisonVolume.enabled = shouldBeEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Damage and Sound Logic ---
|
||||
if (playerCurrentlyInZone && currentPlayerInZone != null)
|
||||
{
|
||||
// Zadawanie obra¿eñ
|
||||
timeSinceLastDamage += Time.deltaTime;
|
||||
if (timeSinceLastDamage >= damageInterval)
|
||||
{
|
||||
ApplyPoisonDamage();
|
||||
timeSinceLastDamage = 0f;
|
||||
}
|
||||
|
||||
// Odtwarzanie dŸwiêku kaszlu
|
||||
if (coughSound != null && coughInterval > 0)
|
||||
{
|
||||
timeSinceLastCough += Time.deltaTime;
|
||||
if (timeSinceLastCough >= coughInterval)
|
||||
{
|
||||
PlayCoughSound();
|
||||
timeSinceLastCough = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
Player enteredPlayer = other.GetComponent<Player>();
|
||||
if (enteredPlayer != null)
|
||||
{
|
||||
if (currentPlayerInZone == null || currentPlayerInZone != enteredPlayer)
|
||||
{
|
||||
currentPlayerInZone = enteredPlayer;
|
||||
playerCurrentlyInZone = true;
|
||||
timeSinceLastDamage = 0f;
|
||||
timeSinceLastCough = 0f; // Reset timera kaszlu
|
||||
|
||||
// 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.
|
||||
|
||||
if (coughSound != null)
|
||||
{
|
||||
PlayCoughSound(); // Kaszel od razu przy wejœciu
|
||||
}
|
||||
//Debug.Log(enteredPlayer.name + " entered poison zone: " + gameObject.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider other)
|
||||
{
|
||||
Player exitedPlayer = other.GetComponent<Player>();
|
||||
if (exitedPlayer != null && exitedPlayer == currentPlayerInZone)
|
||||
{
|
||||
playerCurrentlyInZone = false;
|
||||
// Nie zerujemy currentPlayerInZone tutaj, currentFadeProgress zajmie siê wygaszeniem efektu.
|
||||
//Debug.Log(exitedPlayer.name + " exited poison zone: " + gameObject.name);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyPoisonDamage()
|
||||
{
|
||||
if (currentPlayerInZone != null && currentPlayerInZone.ThirdPersonController != null)
|
||||
{
|
||||
var healthController = currentPlayerInZone.ThirdPersonController;
|
||||
if (healthController != null && !healthController.isDead)
|
||||
{
|
||||
vDamage damageInstance = new vDamage(damageAmount, true);
|
||||
healthController.TakeDamage(damageInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayCoughSound()
|
||||
{
|
||||
if (currentPlayerInZone != null && coughSound != null)
|
||||
{
|
||||
currentPlayerInZone.PlaySingleSound(coughSound, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Characters/PoisonZone.cs.meta
Normal file
2
Assets/Scripts/Characters/PoisonZone.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42b6d889d50a4a84f9b8f341d61afdc6
|
||||
Reference in New Issue
Block a user