Files

109 lines
2.4 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
public class Bullet : MonoBehaviour
{
[Header("Runtime Values")]
private Vector2 direction;
private float speed;
private float damage;
private float maxDistance;
private float distanceTravelled;
private bool initialized;
// Speichert alle Gegner, die diese Kugel bereits getroffen hat.
private HashSet<Enemy> hitEnemies = new HashSet<Enemy>();
private Rigidbody2D rb;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
rb.gravityScale = 0f;
rb.bodyType = RigidbodyType2D.Kinematic;
rb.collisionDetectionMode =
CollisionDetectionMode2D.Continuous;
}
public void Initialize(
Vector2 shootDirection,
float bulletSpeed,
float bulletDamage,
float range
)
{
direction = shootDirection.normalized;
speed = bulletSpeed;
damage = bulletDamage;
maxDistance = range;
// Sprite zeigt standardmäßig mit seiner lokalen Y-Achse nach oben.
float angle =
Mathf.Atan2(direction.y, direction.x)
* Mathf.Rad2Deg - 90f;
transform.rotation =
Quaternion.Euler(0f, 0f, angle);
initialized = true;
}
private void FixedUpdate()
{
if (!initialized)
return;
float remainingDistance =
maxDistance - distanceTravelled;
if (remainingDistance <= 0f)
{
Destroy(gameObject);
return;
}
float movementDistance = Mathf.Min(
speed * Time.fixedDeltaTime,
remainingDistance
);
Vector2 movement =
direction * movementDistance;
rb.MovePosition(rb.position + movement);
distanceTravelled += movementDistance;
if (distanceTravelled >= maxDistance)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
Enemy enemy =
other.GetComponentInParent<Enemy>();
if (enemy == null)
return;
// Bereits getroffenen Gegner ignorieren.
if (!hitEnemies.Add(enemy))
return;
// Keine weiteren Treffer auf tote Gegner.
if (enemy.IsDead)
return;
enemy.TakeDamage(damage);
}
}