205 lines
No EOL
8.2 KiB
C#
205 lines
No EOL
8.2 KiB
C#
namespace UnityCheatSheet
|
|
{
|
|
|
|
using System; // Wird für Events / Actions benötigt
|
|
using System.Collections; // Wird für Coroutinen benötigt
|
|
using UnityEngine; // Der Haupt-Namespace für fast alles in Unity
|
|
|
|
// Das Attribut RequireComponent zwingt Unity dazu, automatisch einen Rigidbody
|
|
// an das GameObject zu hängen, sobald dieses Skript hinzugefügt wird.
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class UnityReferenz : MonoBehaviour
|
|
{
|
|
// ========================================================================
|
|
// 1. VARIABLEN & SICHTBARKEIT (Attribute für den Inspektor)
|
|
// ========================================================================
|
|
|
|
[Header("Basis-Variablen")]
|
|
[Tooltip("Das ist ein Tooltip. Er erscheint, wenn man mit der Maus im Editor darüber fährt.")]
|
|
public int lebenspunkte = 100; // Public: Von überall sichtbar UND im Editor sichtbar
|
|
|
|
[SerializeField]
|
|
private float geschwindigkeit = 5.5f; // Private + SerializeField: Nur in diesem Skript nutzbar, ABER im Editor einstellbar! (Best Practice)
|
|
|
|
[Range(0f, 1f)]
|
|
public float lautstaerke = 0.5f; // Erzeugt einen schönen Schieberegler im Unity Editor
|
|
|
|
[HideInInspector]
|
|
public bool istVersteckt = true; // Public, aber im Editor unsichtbar (für interne Logik)
|
|
|
|
[Header("Referenzen zu anderen Dingen")]
|
|
[SerializeField] private GameObject meinPrefab; // Referenz auf ein Prefab (z.B. ein Schuss oder Gegner)
|
|
[SerializeField] private Transform zielPosition; // Referenz auf eine Position in der Welt (Transform)
|
|
[SerializeField] private Renderer meinRenderer; // Referenz auf eine visuelle Komponente
|
|
|
|
// Private Variablen (weder von außen noch vom Editor erreichbar)
|
|
private Rigidbody meinRigidbody;
|
|
private float zeitSeitStart = 0f;
|
|
|
|
// ========================================================================
|
|
// 2. UNITY LEBENSZYKLUS (Event-Methoden, die Unity automatisch aufruft)
|
|
// ========================================================================
|
|
|
|
// Awake wird als ALLERERSTES aufgerufen, noch bevor das Spiel richtig losgeht.
|
|
// Hier holt man sich Referenzen auf die eigenen Komponenten.
|
|
void Awake()
|
|
{
|
|
// Holt den Rigidbody, der auf DIESEM GameObject liegt.
|
|
meinRigidbody = GetComponent<Rigidbody>();
|
|
|
|
if (meinRigidbody == null)
|
|
{
|
|
Debug.LogError("Hilfe! Hier fehlt ein Rigidbody!"); // Schreibt einen Fehler in die Konsole
|
|
}
|
|
}
|
|
|
|
// Start wird aufgerufen, bevor das erste Update läuft (für Initialisierungen).
|
|
void Start()
|
|
{
|
|
Debug.Log("Das Spiel ist gestartet! Hallo von: " + gameObject.name);
|
|
|
|
// Farbe ändern als Test
|
|
if (meinRenderer != null)
|
|
{
|
|
meinRenderer.material.color = Color.blue;
|
|
}
|
|
|
|
// Startet eine asynchrone Hintergrund-Schleife (Coroutinen, siehe unten)
|
|
StartCoroutine(MeinTimer());
|
|
}
|
|
|
|
// Update wird JEDEN FRAME aufgerufen.
|
|
// Achtung: Wenn das Spiel mit 60 FPS läuft, läuft das hier 60x pro Sekunde!
|
|
void Update()
|
|
{
|
|
// 1. Timer hochzählen mit Time.deltaTime (Zeit, die seit dem letzten Frame vergangen ist)
|
|
zeitSeitStart += Time.deltaTime;
|
|
|
|
// 2. Input abfragen
|
|
AbfrageInput();
|
|
}
|
|
|
|
// FixedUpdate wird in festen Zeitintervallen aufgerufen (Standard: 50x pro Sekunde).
|
|
// ALLES was mit Physik zu tun hat, MUSS hier rein, NICHT in Update!
|
|
void FixedUpdate()
|
|
{
|
|
// Beispiel: Wir schieben das Objekt stetig nach vorne
|
|
// meinRigidbody.AddForce(Vector3.forward * geschwindigkeit);
|
|
}
|
|
|
|
// ========================================================================
|
|
// 3. EIGENE METHODEN: INPUT & BEWEGUNG
|
|
// ========================================================================
|
|
|
|
private void AbfrageInput()
|
|
{
|
|
// TASTENABFRAGE (Einmaliges Drücken)
|
|
if (Input.GetKeyDown(KeyCode.Space))
|
|
{
|
|
Springen();
|
|
}
|
|
|
|
// TASTENABFRAGE (Gedrückt halten)
|
|
if (Input.GetKey(KeyCode.W))
|
|
{
|
|
// Bewege das Objekt direkt (ohne Physik) nach vorne
|
|
// transform.Translate(Vector3.forward * geschwindigkeit * Time.deltaTime);
|
|
}
|
|
|
|
// MAUSABFRAGE (0 = Links, 1 = Rechts, 2 = Mitte)
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
SpawnObjekt();
|
|
}
|
|
}
|
|
|
|
private void Springen()
|
|
{
|
|
// Wirft das Objekt physikalisch in die Luft
|
|
meinRigidbody.AddForce(Vector3.up * 300f);
|
|
Debug.Log("Hüpf!");
|
|
}
|
|
|
|
// ========================================================================
|
|
// 4. INSTANZIIEREN (Spawnen) & ZERSTÖREN
|
|
// ========================================================================
|
|
|
|
public void SpawnObjekt()
|
|
{
|
|
if (meinPrefab == null) return; // Abbruch, wenn kein Prefab hinterlegt ist
|
|
|
|
// Instantiate erstellt eine Kopie des Prefabs an unserer aktuellen Position
|
|
GameObject neuesObjekt = Instantiate(meinPrefab, transform.position, Quaternion.identity);
|
|
|
|
// Wir können das neue Objekt direkt benennen
|
|
neuesObjekt.name = "Klon_von_" + gameObject.name;
|
|
|
|
// Wir können das Objekt nach 5 Sekunden automatisch zerstören lassen
|
|
Destroy(neuesObjekt, 5f);
|
|
}
|
|
|
|
// ========================================================================
|
|
// 5. PHYSIK & KOLLISIONEN
|
|
// ========================================================================
|
|
|
|
// Wird ausgelöst, wenn ein anderes Objekt (mit Collider und Rigidbody) uns RAMMT
|
|
void OnCollisionEnter(Collision collision)
|
|
{
|
|
// Checken, wen wir da gerammt haben (anhand von Tags)
|
|
if (collision.gameObject.CompareTag("Player"))
|
|
{
|
|
Debug.Log("Autsch! Der Spieler hat mich gerammt!");
|
|
|
|
// So können wir z.B. Leben abziehen:
|
|
lebenspunkte -= 10;
|
|
}
|
|
}
|
|
|
|
// Wird ausgelöst, wenn ein Objekt eine unsichtbare Lichtschranke durchquert
|
|
// (Collider muss auf "Is Trigger" gestellt sein)
|
|
void OnTriggerEnter(Collider other)
|
|
{
|
|
Debug.Log("Etwas ist in meinen Trigger gelaufen: " + other.name);
|
|
}
|
|
|
|
// ========================================================================
|
|
// 6. RAYCASTING (Laser-Strahlen schießen)
|
|
// ========================================================================
|
|
|
|
private void SchiesseLaser()
|
|
{
|
|
RaycastHit hit;
|
|
// Schießt einen Strahl von unserer Position nach vorne, 100 Meter weit
|
|
if (Physics.Raycast(transform.position, transform.forward, out hit, 100f))
|
|
{
|
|
Debug.Log("Ich schaue genau auf: " + hit.collider.name);
|
|
|
|
// Wenn man auf das getroffene Objekt zugreifen will:
|
|
// hit.collider.gameObject.GetComponent<AnderesSkript>().MachWas();
|
|
}
|
|
}
|
|
|
|
// ========================================================================
|
|
// 7. COROUTINEN (Dinge, die Zeit brauchen / Warten)
|
|
// ========================================================================
|
|
|
|
// Eine Methode vom Typ IEnumerator läuft parallel und kann pausiert werden
|
|
private IEnumerator MeinTimer()
|
|
{
|
|
Debug.Log("Timer gestartet...");
|
|
|
|
// Pausiert die Ausführung dieser Methode für exakt 2 Sekunden
|
|
yield return new WaitForSeconds(2f);
|
|
|
|
Debug.Log("2 Sekunden sind vorbei!");
|
|
|
|
// Endlos-Schleifen sind hier okay, WEIL sie mit yield return pausiert werden!
|
|
while (lebenspunkte > 0)
|
|
{
|
|
// Mache jede Sekunde einen Tick Schaden
|
|
// lebenspunkte -= 1;
|
|
yield return new WaitForSeconds(1f);
|
|
}
|
|
}
|
|
}
|
|
} |