BITKit/Packages/Runtime~/Unity/Scripts/Entity/Components/Health/EntityHealth.cs

162 lines
4.3 KiB
C#
Raw Normal View History

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