using System; using System.Collections.Generic; using UnityEngine; namespace Ingvar.LiveWatch.TowerDefenceDemo { public class LaserTower : TowerBase { public override TowerType Type => TowerType.Laser; [SerializeField] private float _cooldown = 0.5f; [SerializeField] private int _damage = 5; [SerializeField] private float _radius = 4f; [SerializeField] private Transform _turretPivot; [SerializeField] private ParticleSystem _laserEffect; private LevelScene _levelScene; private bool _isActive; private float _lastFireTime; private float _lastTargetUpdateTime; private Vector2 ourPos => new Vector2(transform.position.x, transform.position.z); private MobMain _previousTarget; private const float targetFindCooldown = 0.05f; private const float rotationSpeed = 5; public override void Enable(LevelScene levelScene) { _isActive = true; _lastFireTime = Time.time; _levelScene = levelScene; } public override void Disable() { _isActive = false; } private void OnDrawGizmos() { Gizmos.DrawWireSphere(transform.position, _radius); } private void Update() { if (!_isActive) return; UpdateRotation(); if (Time.time < _lastFireTime + _cooldown) return; _lastFireTime = Time.time; Fire(); } private void UpdateRotation() { if (Time.time > _lastTargetUpdateTime + targetFindCooldown) _previousTarget = FindNearestTarget(); if (_previousTarget == null || !_previousTarget.IsAlive) return; var targetDirection = _previousTarget.transform.position - _turretPivot.position; var directionNew = Vector3.Slerp(_turretPivot.forward, targetDirection, Time.unscaledDeltaTime * rotationSpeed); _turretPivot.forward = directionNew; } private MobMain FindNearestTarget() { MobMain targetMob = null; foreach (var mob in _levelScene.MobManager.Mobs) { var mobPos = new Vector2(mob.transform.position.x, mob.transform.position.z); var sqrDist = (mobPos - ourPos).sqrMagnitude; if (sqrDist > _radius * _radius) continue; if (targetMob == null || mob.WaypointMover.TravelledDist > targetMob.WaypointMover.TravelledDist) { targetMob = mob; } } return targetMob; } private void Fire() { var targetMob = FindNearestTarget(); if (targetMob != null) { if (targetMob.Health.CurrentHealth <= _damage) Watch.Push("MobLog", $"{targetMob.Id} killed by {Id}") .SetSortOrder(TD_WatchSortOrder.MobLog) ; _turretPivot.forward = targetMob.transform.position - _turretPivot.position; _laserEffect.transform.LookAt(targetMob.transform.position); _laserEffect.Play(); targetMob.Health.TakeDamage(_damage); } } } }