Hsys
PCont
Много времени сохранил себе, сократив названия?
TakeDamage
Что это вообще такое и зачем оно нужно?
DamageCondition
Метод назван так, будто он должен что-то возвращать, но возвращает он ничего.
Почему вообще урон от пик персонаж наносит сам себе, а не пики ему?
Ты хочешь сделать миллион компонентов и потом навешивать их по-одному на персонажа? Не надо так делать. В итоге у тебя будет миллион компонентов, которые зависят друг от друга и, чтобы потом собрать другого персонажа, тебе придется искать всё, из чего он состоит. Делай все через интерфейсы.
Отдельно здоровье
namespace Coroutines
{
public interface IHealth
{
bool IsOver { get; }
void Lose(float amount);
void Restore(float amount);
}
}
using System;
using UnityEngine;
namespace Coroutines
{
public class Health : IHealth
{
private readonly float _max;
private readonly float _min;
private float _current;
public Health(float max, float min = 0)
{
_max = max;
_min = min;
_current = _max;
}
public bool IsOver => _current <= _min;
public void Lose(float amount)
{
if (amount <= 0) throw new ArgumentException();
SetCurrent(_current - amount);
}
public void Restore(float amount)
{
if (amount <= 0) throw new ArgumentException();
SetCurrent(_current + amount);
}
private void SetCurrent(float amount)
{
_current = Mathf.Clamp(amount, _min, _max);
}
}
}
Отдельно персонаж
namespace Coroutines
{
public interface IDamageable
{
bool IsDead { get; }
void ApplyDamage(float amount);
}
}
using UnityEngine;
namespace Coroutines
{
public class Character : MonoBehaviour, IDamageable
{
[SerializeField] private float _maxHp = 100f;
private IHealth _health;
public bool IsDead => _health.IsOver;
private void Awake()
{
_health = new Health(_maxHp);
}
public void ApplyDamage(float amount) => _health.Lose(amount);
}
}
И отдельно ловушка
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Coroutines
{
public class Trap : MonoBehaviour
{
[SerializeField] private float _damage = 10f;
[SerializeField] private float _delay = 2f;
private readonly Dictionary<IDamageable, Coroutine> _targets = new();
private void OnTriggerEnter2D(Collider2D other)
{
if (other.TryGetComponent(out IDamageable damageable))
{
var coroutine = StartCoroutine(Damaging(damageable));
_targets.Add(damageable, coroutine);
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.TryGetComponent(out IDamageable damageable))
{
var coroutine = _targets[damageable];
StopCoroutine(coroutine);
_targets.Remove(damageable);
}
}
private IEnumerator Damaging(IDamageable target)
{
while (target.IsDead == false)
{
target.ApplyDamage(_damage);
yield return new WaitForSeconds(_delay);
}
}
}
}
Как именно должен дамаг наноситься ты не сказал, поэтому у меня каждому персонажу, что зашел в триггер, урон наносится отдельно. На входе в триггер персонаж добавляется в список и стартуется корутина, на выходе корутина завершается и персонаж из списка удаляется. Чтобы завершить определенную корутину, ее нужно кэшировать куда-то.