Damage change, fog fix, Poisone effect postproces. triggers, scripts for posion zone modyfication
This commit is contained in:
@@ -1,75 +1,69 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.Events; // Nadal potrzebne dla UnityEvent ogólnego użytku
|
||||
|
||||
namespace Invector
|
||||
{
|
||||
// Prawdopodobnie te typy są zdefiniowane gdzieś globalnie w namespace Invector
|
||||
// lub w plikach interfejsów. Jeśli nie, trzeba by je tu zdefiniować,
|
||||
// ale zakładam, że kompilator je znajdzie, skoro vDamageReceiver ich używa.
|
||||
// [System.Serializable] public class OnReceiveDamage : UnityEvent<vDamage> { } // Jeśli potrzebna definicja
|
||||
// [System.Serializable] public class OnDead : UnityEvent<GameObject> { } // Jeśli potrzebna definicja
|
||||
|
||||
[vClassHeader("HealthController", iconName = "HealthControllerIcon")]
|
||||
public class vHealthController : vMonoBehaviour, vIHealthController
|
||||
public class vHealthController : vMonoBehaviour, vIHealthController // Upewnij się, że to jest poprawny interfejs
|
||||
{
|
||||
#region Variables
|
||||
|
||||
[vEditorToolbar("Health", order = 0)]
|
||||
[SerializeField] [vReadOnly] protected bool _isDead;
|
||||
[vBarDisplay("maxHealth")] [SerializeField] protected float _currentHealth;
|
||||
[SerializeField][vReadOnly] protected bool _isDead;
|
||||
[vBarDisplay("maxHealth")][SerializeField] protected float _currentHealth;
|
||||
public bool isImmortal = false;
|
||||
[vHelpBox("If you want to start with different value, uncheck this and make sure that the current health has a value greater zero")]
|
||||
public bool fillHealthOnStart = true;
|
||||
public int maxHealth = 100;
|
||||
public int MaxHealth
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxHealth;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
maxHealth = value;
|
||||
}
|
||||
get { return maxHealth; }
|
||||
protected set { maxHealth = value; }
|
||||
}
|
||||
public float currentHealth
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentHealth;
|
||||
}
|
||||
get { return _currentHealth; }
|
||||
protected set
|
||||
{
|
||||
if (_currentHealth != value)
|
||||
{
|
||||
_currentHealth = value;
|
||||
onChangeHealth.Invoke(_currentHealth);
|
||||
}
|
||||
|
||||
if (!_isDead && _currentHealth <= 0)
|
||||
{
|
||||
//_isDead = true;
|
||||
isDead = true;
|
||||
onDead.Invoke(gameObject);
|
||||
}
|
||||
else if (isDead && _currentHealth > 0)
|
||||
{
|
||||
isDead = false;
|
||||
if (onChangeHealth != null) onChangeHealth.Invoke(_currentHealth);
|
||||
}
|
||||
if (!_isDead && _currentHealth <= 0) { isDead = true; }
|
||||
else if (isDead && _currentHealth > 0) { isDead = false; }
|
||||
}
|
||||
}
|
||||
public virtual bool isDead
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isDead && currentHealth <= 0)
|
||||
if (!_isDead && _currentHealth <= 0)
|
||||
{
|
||||
_isDead = true;
|
||||
onDead.Invoke(gameObject);
|
||||
if (_onDead != null) _onDead.Invoke(gameObject);
|
||||
}
|
||||
return _isDead;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isDead = value;
|
||||
if (_isDead != value)
|
||||
{
|
||||
_isDead = value;
|
||||
if (_isDead)
|
||||
{
|
||||
if (_onDead != null) _onDead.Invoke(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public float healthRecovery = 0f;
|
||||
@@ -78,38 +72,46 @@ namespace Invector
|
||||
public float currentHealthRecoveryDelay;
|
||||
[vEditorToolbar("Events", order = 100)]
|
||||
public List<CheckHealthEvent> checkHealthEvents = new List<CheckHealthEvent>();
|
||||
|
||||
// Używamy typów zdarzeń zdefiniowanych przez Invector (OnReceiveDamage, OnDead)
|
||||
[SerializeField] protected OnReceiveDamage _onStartReceiveDamage = new OnReceiveDamage();
|
||||
[SerializeField] protected OnReceiveDamage _onReceiveDamage = new OnReceiveDamage();
|
||||
[SerializeField] protected OnDead _onDead = new OnDead();
|
||||
public ValueChangedEvent onChangeHealth;
|
||||
[SerializeField] protected OnDead _onDead = new OnDead(); // Zakładając, że typ OnDead istnieje
|
||||
|
||||
[System.Serializable]
|
||||
public class ValueChangedEvent : UnityEvent<float> { }
|
||||
public ValueChangedEvent onChangeHealth = new ValueChangedEvent();
|
||||
public UnityEvent onResetHealth = new UnityEvent(); // Standardowy UnityEvent
|
||||
|
||||
public OnReceiveDamage onStartReceiveDamage { get { return _onStartReceiveDamage; } protected set { _onStartReceiveDamage = value; } }
|
||||
public OnReceiveDamage onReceiveDamage { get { return _onReceiveDamage; } protected set { _onReceiveDamage = value; } }
|
||||
public OnDead onDead { get { return _onDead; } protected set { _onDead = value; } }
|
||||
public UnityEvent onResetHealth;
|
||||
internal bool inHealthRecovery;
|
||||
|
||||
// Właściwości implementujące interfejs, używając typów Invectora
|
||||
public OnReceiveDamage onStartReceiveDamage { get { return _onStartReceiveDamage; } } // Usunięto 'protected set' aby pasowało do get-only interfejsu
|
||||
public OnReceiveDamage onReceiveDamage { get { return _onReceiveDamage; } } // Usunięto 'protected set'
|
||||
public OnDead onDead { get { return _onDead; } } // Usunięto 'protected set'
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (fillHealthOnStart)
|
||||
currentHealth = maxHealth;
|
||||
if (fillHealthOnStart) currentHealth = maxHealth;
|
||||
currentHealthRecoveryDelay = healthRecoveryDelay;
|
||||
}
|
||||
|
||||
protected virtual bool canRecoverHealth
|
||||
{
|
||||
get
|
||||
{
|
||||
return (currentHealth >= 0 && healthRecovery > 0 && currentHealth < maxHealth);
|
||||
}
|
||||
get { return (_currentHealth >= 0 && healthRecovery > 0 && _currentHealth < maxHealth && !_isDead); }
|
||||
}
|
||||
|
||||
|
||||
protected virtual IEnumerator RecoverHealth()
|
||||
{
|
||||
inHealthRecovery = true;
|
||||
while (canRecoverHealth && !isDead)
|
||||
while (currentHealthRecoveryDelay > 0 && !_isDead)
|
||||
{
|
||||
currentHealthRecoveryDelay -= Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
while (canRecoverHealth)
|
||||
{
|
||||
HealthRecovery();
|
||||
yield return null;
|
||||
@@ -119,149 +121,122 @@ namespace Invector
|
||||
|
||||
protected virtual void HealthRecovery()
|
||||
{
|
||||
if (!canRecoverHealth||isDead) return;
|
||||
if (currentHealthRecoveryDelay > 0)
|
||||
currentHealthRecoveryDelay -= Time.deltaTime;
|
||||
else
|
||||
if (!canRecoverHealth) return;
|
||||
if (_currentHealth < maxHealth)
|
||||
{
|
||||
if (currentHealth > maxHealth)
|
||||
currentHealth = maxHealth;
|
||||
if (currentHealth < maxHealth)
|
||||
currentHealth += healthRecovery * Time.deltaTime;
|
||||
_currentHealth += healthRecovery * Time.deltaTime;
|
||||
_currentHealth = Mathf.Min(_currentHealth, maxHealth);
|
||||
if (onChangeHealth != null) onChangeHealth.Invoke(_currentHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increase or decrease currentHealth (Positive or Negative Values)
|
||||
/// </summary>
|
||||
/// <param name="value">Value to change</param>
|
||||
public virtual void AddHealth(int value)
|
||||
{
|
||||
currentHealth += value;
|
||||
currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth);
|
||||
if (!isDead && currentHealth <= 0)
|
||||
{
|
||||
isDead = true;
|
||||
onDead.Invoke(gameObject);
|
||||
}
|
||||
HandleCheckHealthEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the currentHealth of Character
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public virtual void ChangeHealth(int value)
|
||||
{
|
||||
currentHealth = value;
|
||||
currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth);
|
||||
if (!isDead && currentHealth <= 0)
|
||||
{
|
||||
isDead = true;
|
||||
onDead.Invoke(gameObject);
|
||||
}
|
||||
HandleCheckHealthEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset's current health to specific health value
|
||||
/// </summary>
|
||||
/// <param name="health">target health</param>
|
||||
public virtual void AddHealth(int value) { currentHealth += value; }
|
||||
public virtual void ChangeHealth(int value) { currentHealth = value; }
|
||||
public virtual void ResetHealth(float health)
|
||||
{
|
||||
currentHealth = health;
|
||||
onResetHealth.Invoke();
|
||||
if (isDead) isDead = false;
|
||||
currentHealth = Mathf.Clamp(health, 0, maxHealth);
|
||||
if (onResetHealth != null) onResetHealth.Invoke();
|
||||
if (_isDead && _currentHealth > 0) isDead = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Reset's current health to max health
|
||||
/// </summary>
|
||||
public virtual void ResetHealth()
|
||||
{
|
||||
currentHealth = maxHealth;
|
||||
onResetHealth.Invoke();
|
||||
if (isDead) isDead = false;
|
||||
if (onResetHealth != null) onResetHealth.Invoke();
|
||||
if (_isDead) isDead = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the MaxHealth of Character
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public virtual void ChangeMaxHealth(int value)
|
||||
{
|
||||
maxHealth += value;
|
||||
if (maxHealth < 0)
|
||||
maxHealth = 0;
|
||||
if (maxHealth < 0) maxHealth = 0;
|
||||
if (_currentHealth > maxHealth) currentHealth = maxHealth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a value to HealthRecovery to start recovering health
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public virtual void SetHealthRecovery(float value)
|
||||
{
|
||||
healthRecovery = value;
|
||||
StartCoroutine(RecoverHealth());
|
||||
if (!inHealthRecovery && canRecoverHealth && gameObject.activeInHierarchy)
|
||||
{
|
||||
StartCoroutine(RecoverHealth());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply Damage to Current Health
|
||||
/// </summary>
|
||||
/// <param name="damage">damage</param>
|
||||
public virtual void TakeDamage(vDamage damage)
|
||||
{
|
||||
if (damage != null)
|
||||
{
|
||||
onStartReceiveDamage.Invoke(damage);
|
||||
currentHealthRecoveryDelay = currentHealth <= 0 ? 0 : healthRecoveryDelay;
|
||||
if (damage != null && !_isDead)
|
||||
{
|
||||
if (inHealthRecovery)
|
||||
{
|
||||
StopCoroutine(RecoverHealth());
|
||||
inHealthRecovery = false;
|
||||
}
|
||||
currentHealthRecoveryDelay = healthRecoveryDelay;
|
||||
|
||||
if (currentHealth > 0 && !isImmortal)
|
||||
{
|
||||
currentHealth -= damage.damageValue;
|
||||
// Użyj flagi ignoreAllHitEffects zdefiniowanej w Twoim zmodyfikowanym vDamage.cs
|
||||
if (_onStartReceiveDamage != null && !damage.ignoreAllHitEffects)
|
||||
{
|
||||
_onStartReceiveDamage.Invoke(damage);
|
||||
}
|
||||
|
||||
if (_currentHealth > 0 && !isImmortal)
|
||||
{
|
||||
_currentHealth -= damage.damageValue;
|
||||
if (onChangeHealth != null) onChangeHealth.Invoke(_currentHealth);
|
||||
}
|
||||
|
||||
// Użyj flagi ignoreAllHitEffects zdefiniowanej w Twoim zmodyfikowanym vDamage.cs
|
||||
if (damage.damageValue > 0 && _onReceiveDamage != null && !damage.ignoreAllHitEffects)
|
||||
{
|
||||
_onReceiveDamage.Invoke(damage);
|
||||
}
|
||||
|
||||
if (_currentHealth <= 0 && !_isDead)
|
||||
{
|
||||
isDead = true;
|
||||
}
|
||||
|
||||
if (damage.damageValue > 0)
|
||||
onReceiveDamage.Invoke(damage);
|
||||
HandleCheckHealthEvents();
|
||||
|
||||
if (!_isDead && healthRecovery > 0 && !inHealthRecovery && gameObject.activeInHierarchy)
|
||||
{
|
||||
StartCoroutine(RecoverHealth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void HandleCheckHealthEvents()
|
||||
{
|
||||
var events = checkHealthEvents.FindAll(e => (e.healthCompare == CheckHealthEvent.HealthCompare.Equals && currentHealth.Equals(e.healthToCheck)) ||
|
||||
(e.healthCompare == CheckHealthEvent.HealthCompare.HigherThan && currentHealth > (e.healthToCheck)) ||
|
||||
(e.healthCompare == CheckHealthEvent.HealthCompare.LessThan && currentHealth < (e.healthToCheck)));
|
||||
|
||||
for (int i = 0; i < events.Count; i++)
|
||||
if (checkHealthEvents == null) return;
|
||||
for (int i = 0; i < checkHealthEvents.Count; i++)
|
||||
{
|
||||
events[i].OnCheckHealth.Invoke();
|
||||
var e = checkHealthEvents[i];
|
||||
if (e == null || e.OnCheckHealth == null) continue;
|
||||
bool conditionMet = false;
|
||||
switch (e.healthCompare)
|
||||
{
|
||||
case CheckHealthEvent.HealthCompare.Equals:
|
||||
conditionMet = Mathf.Approximately(_currentHealth, e.healthToCheck);
|
||||
break;
|
||||
case CheckHealthEvent.HealthCompare.HigherThan:
|
||||
conditionMet = _currentHealth > e.healthToCheck;
|
||||
break;
|
||||
case CheckHealthEvent.HealthCompare.LessThan:
|
||||
conditionMet = _currentHealth < e.healthToCheck;
|
||||
break;
|
||||
}
|
||||
if (conditionMet)
|
||||
{
|
||||
e.OnCheckHealth.Invoke();
|
||||
}
|
||||
}
|
||||
if (currentHealth < maxHealth && this.gameObject.activeInHierarchy && !inHealthRecovery)
|
||||
StartCoroutine(RecoverHealth());
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class CheckHealthEvent
|
||||
{
|
||||
public int healthToCheck;
|
||||
public float healthToCheck;
|
||||
public bool disableEventOnCheck;
|
||||
|
||||
public enum HealthCompare
|
||||
{
|
||||
Equals,
|
||||
HigherThan,
|
||||
LessThan
|
||||
}
|
||||
|
||||
public enum HealthCompare { Equals, HigherThan, LessThan }
|
||||
public HealthCompare healthCompare = HealthCompare.Equals;
|
||||
|
||||
public UnityEngine.Events.UnityEvent OnCheckHealth;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ValueChangedEvent : UnityEvent<float>
|
||||
{
|
||||
|
||||
public UnityEvent OnCheckHealth = new UnityEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Invector
|
||||
{
|
||||
[System.Serializable]
|
||||
@@ -14,7 +15,7 @@ namespace Invector
|
||||
public bool ignoreDefense;
|
||||
[Tooltip("Activated Ragdoll when hit the Character")]
|
||||
public bool activeRagdoll;
|
||||
[vHideInInspector("activeRagdoll"),Tooltip("Time to keep Ragdoll active")]
|
||||
[vHideInInspector("activeRagdoll"), Tooltip("Time to keep Ragdoll active")]
|
||||
public float senselessTime;
|
||||
[HideInInspector]
|
||||
public Transform sender;
|
||||
@@ -22,7 +23,7 @@ namespace Invector
|
||||
public Transform receiver;
|
||||
[HideInInspector]
|
||||
public Vector3 hitPosition;
|
||||
public bool hitReaction = true;
|
||||
public bool hitReaction = true; // To pole Invectora pozostaje
|
||||
[HideInInspector]
|
||||
public int recoil_id = 0;
|
||||
[HideInInspector]
|
||||
@@ -30,32 +31,65 @@ namespace Invector
|
||||
public string damageType;
|
||||
[HideInInspector] public Vector3 force;
|
||||
|
||||
// >>> NASZE NOWE POLE <<<
|
||||
[Tooltip("If true, will attempt to bypass standard hit reaction animations, sounds, and events like OnReceiveDamage.")]
|
||||
public bool ignoreAllHitEffects = false;
|
||||
|
||||
public vDamage()
|
||||
{
|
||||
this.damageValue = 15;
|
||||
this.staminaBlockCost = 5;
|
||||
this.staminaRecoveryDelay = 1;
|
||||
this.hitReaction = true;
|
||||
this.ignoreAllHitEffects = false; // Domyślnie efekty są włączone
|
||||
}
|
||||
|
||||
public vDamage(int value)
|
||||
{
|
||||
this.damageValue = value;
|
||||
this.hitReaction = true;
|
||||
this.ignoreAllHitEffects = false; // Domyślnie efekty są włączone
|
||||
}
|
||||
|
||||
public vDamage(int value, bool ignoreReaction)
|
||||
// Ten konstruktor już istniał, zmodyfikujemy go lekko
|
||||
// lub dodamy nowy, jeśli chcemy zachować stary w niezmienionej formie.
|
||||
// Dla uproszczenia, zmodyfikujmy ten, aby przyjmował naszą nową flagę.
|
||||
// Jeśli `ignoreReactionOrEffects` jest true, ustawiamy obie flagi.
|
||||
public vDamage(int value, bool ignoreReactionAndAllEffects)
|
||||
{
|
||||
this.damageValue = value;
|
||||
this.hitReaction = !ignoreReaction;
|
||||
if (ignoreReaction)
|
||||
this.ignoreAllHitEffects = ignoreReactionAndAllEffects; // Ustawiamy naszą nową flagę
|
||||
|
||||
if (ignoreReactionAndAllEffects)
|
||||
{
|
||||
this.hitReaction = false; // Jeśli ignorujemy wszystkie efekty, to reakcję też
|
||||
this.recoil_id = -1;
|
||||
this.reaction_id = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.hitReaction = true; // W przeciwnym razie standardowa reakcja
|
||||
}
|
||||
}
|
||||
|
||||
// Możesz też dodać bardziej specyficzny konstruktor tylko dla naszej flagi,
|
||||
// jeśli chcesz mieć większą kontrolę:
|
||||
/*
|
||||
public vDamage(int value, bool setHitReaction, bool setIgnoreAllHitEffects)
|
||||
{
|
||||
this.damageValue = value;
|
||||
this.hitReaction = setHitReaction;
|
||||
this.ignoreAllHitEffects = setIgnoreAllHitEffects;
|
||||
if (!setHitReaction) // Jeśli hitReaction jest false
|
||||
{
|
||||
this.recoil_id = -1;
|
||||
this.reaction_id = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public vDamage(vDamage damage)
|
||||
|
||||
public vDamage(vDamage damage) // Konstruktor kopiujący
|
||||
{
|
||||
this.damageValue = damage.damageValue;
|
||||
this.staminaBlockCost = damage.staminaBlockCost;
|
||||
@@ -70,6 +104,9 @@ namespace Invector
|
||||
this.hitPosition = damage.hitPosition;
|
||||
this.senselessTime = damage.senselessTime;
|
||||
this.force = damage.force;
|
||||
this.hitReaction = damage.hitReaction; // Skopiuj oryginalne pole hitReaction
|
||||
// >>> SKOPIUJ NASZE NOWE POLE <<<
|
||||
this.ignoreAllHitEffects = damage.ignoreAllHitEffects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user