using UnityEngine; using DepthsOfGreed.HandbookUI; public class Turret : MonoBehaviour { [Header("Tower Data")] [SerializeField] private HandbookTowerEntry towerData; [Header("Turret Setup")] [SerializeField] private Transform turret; [SerializeField] private Transform tip; [SerializeField] private float rotationSpeed = 360f; [Header("Projectile Setup")] [SerializeField] private GameObject bulletPrefab; [SerializeField] private float bulletSpeed = 8f; private CombatDefinition combatStats; private float nextAttackTime; private Enemy currentTarget; private void Start() { if (towerData == null) { Debug.LogError( "TowerShooting: Kein HandbookTowerEntry zugewiesen!", this ); enabled = false; return; } if (turret == null || tip == null || bulletPrefab == null) { Debug.LogError( "TowerShooting: Turret, Tip oder Bullet Prefab fehlt!", this ); enabled = false; return; } combatStats = towerData.CreateCombatSnapshot(0); } private void Update() { if (combatStats == null) return; // Ziel innerhalb der Reichweite suchen. currentTarget = FindTarget(); if (currentTarget != null) { RotateTowardsTarget(); TryShoot(); } else { // Zur ursprünglichen Ausrichtung zurückkehren. RotateTowardsOrigin(); } } private Enemy FindTarget() { Enemy[] enemies = FindObjectsByType( FindObjectsSortMode.None ); Enemy closestEnemy = null; float closestDistance = float.MaxValue; float rangeSquared = combatStats.range * combatStats.range; foreach (Enemy enemy in enemies) { if (enemy == null || enemy.IsDead) continue; Vector2 difference = enemy.transform.position - transform.position; float distanceSquared = difference.sqrMagnitude; if (distanceSquared > rangeSquared) continue; if (distanceSquared < closestDistance) { closestDistance = distanceSquared; closestEnemy = enemy; } } return closestEnemy; } private void RotateTowardsTarget() { Vector3 worldDirection = currentTarget.transform.position - turret.position; // Richtung in den lokalen Raum der Turmbasis umwandeln. Vector3 localDirection = turret.parent != null ? turret.parent.InverseTransformDirection(worldDirection) : worldDirection; float targetAngle = Mathf.Atan2(localDirection.y, localDirection.x) * Mathf.Rad2Deg - 90f; Quaternion targetRotation = Quaternion.Euler(0f, 0f, targetAngle); turret.localRotation = Quaternion.RotateTowards( turret.localRotation, targetRotation, rotationSpeed * Time.deltaTime ); } private void RotateTowardsOrigin() { turret.localRotation = Quaternion.RotateTowards( turret.localRotation, Quaternion.identity, rotationSpeed * Time.deltaTime ); } private void TryShoot() { if (combatStats.attacksPerSecond <= 0f) return; if (Time.time < nextAttackTime) return; Shoot(); float attackInterval = 1f / combatStats.attacksPerSecond; nextAttackTime = Time.time + attackInterval; } private void Shoot() { GameObject bulletObject = Instantiate( bulletPrefab, tip.position, tip.rotation ); Bullet bullet = bulletObject.GetComponent(); if (bullet == null) { Debug.LogError( "TowerShooting: Bullet Prefab besitzt kein TowerBullet-Skript!", bulletObject ); Destroy(bulletObject); return; } bullet.Initialize( tip.up, bulletSpeed, combatStats.damagePerHit, combatStats.range ); } private void OnDrawGizmosSelected() { if (towerData == null) return; Gizmos.color = Color.red; Gizmos.DrawWireSphere( transform.position, towerData.combat.range ); } }