132 lines
3.2 KiB
C#

using UnityEngine;
using System;
public class Missile : AbstractProjectile
{
[Header("Компоненты")]
[SerializeField] private Rigidbody rb;
[SerializeField] private Damager damager;
[SerializeField] private Collider missileCollider;
[SerializeField] private float acceleration = 30f;
[SerializeField] GameObject Vfx;
[Header("Water Defense")]
[SerializeField] private bool checkWaterCollision = true;
[SerializeField] private float WaterYPosition = 17f;
private Transform target;
private Vector3 intermediatePoint;
private GameObject owner;
private float currentSpeed;
private MissileState state;
private bool isLaunched = false;
public event Action<Missile> OnMissileDestroyed;
private enum MissileState
{
Rise,
Pursue
}
public void Launch(GameObject owner, Transform target, Vector3 intermediatePoint, float damage, float riseSpeed/*, float pursueSpeed*/)
{
this.owner = owner;
this.target = target;
this.intermediatePoint = intermediatePoint;
currentSpeed = riseSpeed;
state = MissileState.Rise;
isLaunched = true;
// Инициализируем урон
if (damager != null)
{
damager.Initialize(owner, damage);
damager.OnHit += DestroyMissile;
}
}
private void FixedUpdate()
{
if (!isLaunched) return;
if (checkWaterCollision && IsInWater())
{
DestroyMissile();
return;
}
switch (state)
{
case MissileState.Rise:
RisePhase();
break;
case MissileState.Pursue:
PursuePhase();
break;
}
// Применяем движение
rb.linearVelocity = transform.forward * currentSpeed;
}
private bool IsInWater() => transform.position.y < WaterYPosition;
private void RisePhase()
{
Vector3 directionToIntermediate = (intermediatePoint - transform.position).normalized;
transform.rotation = Quaternion.LookRotation(directionToIntermediate);
if (Vector3.Distance(transform.position, intermediatePoint) < 1f)
SwitchToPursuePhase();
}
private void SwitchToPursuePhase()
{
state = MissileState.Pursue;
currentSpeed = 0;
if (target == null)
{
DestroyMissile();
return;
}
}
private void PursuePhase()
{
Vector3 directionToTarget = (target.position - transform.position).normalized;
currentSpeed += acceleration * Time.deltaTime;
transform.rotation = Quaternion.LookRotation(directionToTarget);
}
private void DestroyMissile()
{
if (!isLaunched) return;
isLaunched = false;
damager.OnHit -= DestroyMissile;
OnMissileDestroyed?.Invoke(this);
Vfx.transform.parent = null;
Vfx.GetComponent<ParticleSystem>().Stop();
Destroy(Vfx.gameObject, 2);
Destroy(gameObject);
}
private void OnDestroy()
{
if (isLaunched)
{
OnMissileDestroyed?.Invoke(this);
}
}
}