132 lines
3.2 KiB
C#
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);
|
|
}
|
|
}
|
|
} |