Files
OTG_6/Assets/_Scripts/Effects/FireballEffect.cs
T
2026-06-04 21:37:43 +03:00

84 lines
2.4 KiB
C#

using OTG.Lab06.Abilities;
using OTG.Lab06.Core;
using UnityEngine;
namespace OTG.Lab06.Effects
{
[RequireComponent(typeof(Collider))]
public sealed class FireballEffect : AbilityEffect
{
[SerializeField] private float speed = 18f;
[SerializeField] private float lifeTime = 4f;
[SerializeField] private LayerMask hitMask = ~0;
private AbilityCastContext context;
private Vector3 direction;
private float remainingLife;
private bool activated;
public override void Activate(AbilityCastContext context)
{
this.context = context;
direction = context.Forward;
remainingLife = Mathf.Min(lifeTime, Mathf.Max(0.5f, context.Ability.castRange / Mathf.Max(1f, speed)));
activated = true;
transform.position = context.Origin + direction * 0.9f;
transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
}
private void Awake()
{
Collider ownCollider = GetComponent<Collider>();
ownCollider.isTrigger = true;
}
private void Update()
{
if (!activated)
{
return;
}
float step = speed * Time.deltaTime;
if (Physics.Raycast(transform.position, direction, out RaycastHit hit, step, hitMask, QueryTriggerInteraction.Ignore))
{
ApplyHit(hit.collider);
return;
}
transform.position += direction * step;
remainingLife -= Time.deltaTime;
if (remainingLife <= 0f)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter(Collider other)
{
if (!activated || other.transform == context.Caster)
{
return;
}
ApplyHit(other);
}
private void ApplyHit(Collider hitCollider)
{
if (hitCollider.transform == context.Caster || hitCollider.GetComponentInParent<AbilityEffect>() != null)
{
return;
}
IDamageable damageable = hitCollider.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsAlive)
{
damageable.TakeDamage(context.Ability.damage);
}
Destroy(gameObject);
}
}
}