using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting.Contexts; using UnityEngine; using UnityEngine.Events; namespace BITKit.Entities { public interface IHealthCallback { void OnSetAlive(bool alive); void OnSetHP(int hp); } [Serializable] public class UnityEventHealthCallback : IHealthCallback { [SerializeField] private UnityEvent onSetHP; [SerializeField] private UnityEvent onSetAlive; [SerializeField] private UnityEvent onSetDead; public void OnSetAlive(bool alive) { if (alive) { onSetAlive.Invoke(); } else { onSetDead.Invoke(); } } public void OnSetHP(int hp) { onSetHP.Invoke(hp); } } public interface IHealth { public event Action OnSetHealthPoint; public event Action OnSetAlive; int HealthPoint { get; set; } int MaxHealthPoint { get; set; } bool IsAlive { get; } } public class EntityHealth : EntityComponent, IHealth { [Header(Constant.Header.Settings)] [SerializeField] private int healthPoint = 100; [SerializeField] private int maxHealthPoint = 100; [Header(Constant.Header.Events)] [SerializeField] private UnityEvent onSetAlive = new(); [Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector] private IHealthCallback[] additiveCallback; public event Action OnSetHealthPoint; public event Action OnSetAlive; public int HealthPoint { get => healthPoint; set => OnHealthPointChangedInternal(healthPoint, value); } public int MaxHealthPoint { get => maxHealthPoint; set => maxHealthPoint = value; } public bool IsAlive { get; private set; } public override void Initialize(IEntity _entity) { base.Initialize(_entity); _entity.Set(this); _entity.Set(this); } public override void OnAwake() { entity.AddListener(OnDamage); } public override void OnStart() { IsAlive = healthPoint >= 0; OnSetAliveInternal(IsAlive); OnHealthPointChangedInternal(0, healthPoint); } private void OnHealthPointChangedInternal(int old, int newHP) { healthPoint = newHP; var _isAlive = newHP >= 0; if (_isAlive != IsAlive) { OnSetAliveInternal(IsAlive = _isAlive); } //entity.Invoke(_onSetHP, newHP); //entity.Set("HP", newHP); foreach (var x in entity.GetCallbacks()) { x.OnSetHP(newHP); } foreach (var x in additiveCallback) { x.OnSetHP(newHP); } OnSetHealthPoint?.Invoke(newHP); } private void OnSetAliveInternal(bool alive) { foreach (var x in entity.GetCallbacks()) { x.OnSetAlive(alive); } foreach (var x in additiveCallback) { x.OnSetAlive(alive); } //entity.Invoke(_onSetAlive, alive); //entity.Set(_isAlive, alive); onSetAlive.Invoke(alive); OnSetAlive?.Invoke(alive); } private void AddHP(int hp) { OnHealthPointChangedInternal(healthPoint, healthPoint += hp); } private void OnDamage(DamageMessage damageMessage) { if (damageMessage.target == entity) AddHP(-damageMessage.damage); } #if UNITY_EDITOR [BIT] public void SetAlive() { BITAppForUnity.ThrowIfNotPlaying(); OnHealthPointChangedInternal(-1, 100); } [BIT] public void SetDead() { BITAppForUnity.ThrowIfNotPlaying(); OnHealthPointChangedInternal(100, -1); } #endif } }