Happy_Forest/Assets/Scripts/MovingScript.cs

89 lines
3.7 KiB
C#
Raw Normal View History

2026-08-02 21:58:26 +02:00
using UnityEngine;
namespace HappyForest.Prototypen
{
//// Zwingt Unity, der Pille automatisch einen Rigidbody zu geben, falls noch keiner da ist
[RequireComponent(typeof(Rigidbody))]
public class WanderndePille : MonoBehaviour
{
[SerializeField] private float geschwindigkeit = 5f;
[SerializeField] private string wandTag = "Wand"; // Nach diesem Etikett suchen wir
[SerializeField] private string pilleTag = "Pille"; // NEU: Damit sie sich auch gegenseitig erkennen
private Rigidbody meinRigidbody;
private float zeitLetzterDrehung = 0f; // NEU: Ein Timer, damit sie sich nicht zu oft dreht
void Start()
{
// Rigidbody-Referenz holen
meinRigidbody = GetComponent<Rigidbody>();
// WICHTIG: Damit die Pille nicht umfällt UND nicht durch Kollisionen anfängt zu trudeln!
// FreezeRotation sperrt direkt alle drei Achsen (X, Y und Z) für die Physik-Engine.
meinRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
// Zum Start direkt eine zufällige Richtung aussuchen
NeueRichtungWaehlen(false);
}
void FixedUpdate()
{
// NEU: Fällt die Pille in den Abgrund?
// Wenn Y kleiner als -10 ist, löscht sie sich selbst und beendet die Methode sofort mit "return".
if (transform.position.y < -10f)
{
Destroy(gameObject);
return;
}
// Wir setzen die Geschwindigkeit des Rigidbodys konstant auf unsere Blickrichtung (forward)
// Die Y-Geschwindigkeit (Fallen) behalten wir bei, damit Schwerkraft noch funktioniert
Vector3 neueGeschwindigkeit = transform.forward * geschwindigkeit;
neueGeschwindigkeit.y = meinRigidbody.linearVelocity.y;
meinRigidbody.linearVelocity = neueGeschwindigkeit;
}
// Wird automatisch von Unity aufgerufen, wenn unser Collider einen anderen Collider rammt
void OnCollisionEnter(Collision collision)
{
// Haben wir eine Wand ODER eine andere Pille getroffen UND ist die letzte Drehung lang genug her? (Cooldown)
if ((collision.gameObject.CompareTag(wandTag) || collision.gameObject.CompareTag(pilleTag)) && Time.time > zeitLetzterDrehung + 0.2f)
{
zeitLetzterDrehung = Time.time; // Zeitstempel merken
NeueRichtungWaehlen(true);
}
}
// Sicherheitsnetz: Falls sie doch mal hängen bleibt und an der Wand reibt
void OnCollisionStay(Collision collision)
{
if ((collision.gameObject.CompareTag(wandTag) || collision.gameObject.CompareTag(pilleTag)) && Time.time > zeitLetzterDrehung + 0.2f)
{
zeitLetzterDrehung = Time.time;
NeueRichtungWaehlen(true);
}
}
private void NeueRichtungWaehlen(bool wandGetroffen)
{
float neuerWinkel;
if (wandGetroffen)
{
// Wenn wir eine Wand treffen, drehen wir uns um ca. 180 Grad um!
// (Mit ein bisschen Zufall zwischen 130 und 230 Grad)
float aktuellerWinkel = transform.eulerAngles.y;
neuerWinkel = aktuellerWinkel + Random.Range(130f, 230f);
}
else
{
// Wählt zum Start eine völlig zufällige Zahl zwischen 0 und 360 Grad
neuerWinkel = Random.Range(0f, 360f);
}
// Dreht die Pille auf der Y-Achse (die Achse, die nach oben zeigt)
transform.rotation = Quaternion.Euler(0f, neuerWinkel, 0f);
}
}
}