89 lines
3.7 KiB
C#
89 lines
3.7 KiB
C#
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|