using UnityEngine;
using System.Collections.Generic;
using Fusion;
namespace Projectiles
{
///
/// An area that deals damage over time to any IHitTarget that stays inside it.
///
public class DamageArea : NetworkBehaviour
{
// PRIVATE MEMBERS
[SerializeField]
private float _damagePerSecond = 20f;
[SerializeField]
private int _hitsPerSecond = 4;
[Networked]
private TickTimer _cooldown { get; set; }
private HashSet _targets = new();
// NetworkBehaviour INTERFACE
public override void FixedUpdateNetwork()
{
if (_damagePerSecond <= 0f)
return;
// Remove invalid targets
_targets.RemoveWhere(t => t.IsActive == false);
if (_cooldown.ExpiredOrNotRunning(Runner) == true)
{
Fire();
}
}
// MONOBEHAVIOUR
private void OnTriggerEnter(Collider other)
{
if (HasStateAuthority == false)
return;
var target = other.GetComponentInParent();
if (target != null)
{
_targets.Add(target);
}
}
private void OnTriggerExit(Collider other)
{
if (HasStateAuthority == false)
return;
var target = other.GetComponentInParent();
if (target != null)
{
_targets.Remove(target);
}
}
// PRIVATE METHODS
private void Fire()
{
// Restart the hit interval
_cooldown = TickTimer.CreateFromSeconds(Runner, 1f / _hitsPerSecond);
float damage = _damagePerSecond / _hitsPerSecond;
foreach (var target in _targets)
{
var targetPosition = (target as MonoBehaviour).transform.position;
HitData hitData = new HitData();
hitData.Action = EHitAction.Damage;
hitData.Amount = damage;
hitData.Position = targetPosition;
hitData.InstigatorRef = Object.InputAuthority;
hitData.Direction = (targetPosition - transform.position).normalized;
hitData.Normal = Vector3.up;
hitData.Target = target;
hitData.HitType = EHitType.Suicide;
HitUtility.ProcessHit(ref hitData);
}
}
}
}