Files
2025-08-31 18:14:07 -04:00

111 lines
3.4 KiB
C#

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);
}
}
}
}