Dateien sortiert, Hintergrund angepasst, Platzierungslogik und Basis für Combat angelegt. Gewehr schießt und Gegner nehmen Schaden
This commit is contained in:
1 parent
02b9ddb226
commit
e8c81646c4
59 files changed
+2616
-179
No files matched your search
@@ -0,0 +1,209 @@
|
||||
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<Enemy>(
|
||||
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<Bullet>();
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user