Menu
CoddyTech

Dinge schieben

Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 40 von 56.

Ein CharacterController schiebt nichts: Bewegt man ihn gegen eine Kiste mit einem Rigidbody, bleibt er stehen, als wäre dort eine Wand. Stattdessen ruft Unity für jeden Collider, den ein Move berührt, auch für den Boden, OnControllerColliderHit(ControllerColliderHit hit) in den eigenen Skripten des Controllers auf, und das Skript entscheidet, was passiert. hit.collider ist das, was berührt wurde, hit.moveDirection die Richtung des Move, der es berührt hat, und hit.normal die Richtung, in die die Oberfläche am Kontaktpunkt zeigt. Dies ist Unitys eigenes Schiebeskript:

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // nichts zum Schieben
    if (hit.moveDirection.y < -0.3f) return;        // es befindet sich unter unseren Füßen

    Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
    body.linearVelocity = pushDir * pushPower;
}

Jedes return hat einen Grund. Der Boden und die Wände haben keinen Rigidbody, daher ist body für sie null, und sie werden bei fast jedem Move berührt. Ein kinematischer Körper bewegt sich nur, wenn sein eigenes Skript ihn bewegt, daher bewirkt eine Geschwindigkeit bei ihm nichts. Ein Move, der steil nach unten zeigt, hat etwas unter den Füßen berührt, und die Kiste, auf der der Spieler steht, sollte nicht weggeschoben werden.

Die Schubrichtung behält nur x und z bei, sodass eine Kiste über den Boden gleitet, statt in ihn hineingedrückt zu werden. Wird linearVelocity gesetzt, statt eine Kraft hinzuzufügen, bewegen sich eine leichte und eine schwere Kiste mit derselben Geschwindigkeit; body.AddForce(pushDir * pushPower, ForceMode.Impulse) würde die schwere weniger stark schieben.

challenge icon

Aufgabe

Mittel

Tritt die Bälle über den Hof. Der Player läuft mit einem CharacterController (Walker.cs, fertig). Schreibe Kicker.cs, ebenfalls auf dem Player. Im Inspector werden kickPower (6) und lift (4) festgelegt.

  • Wenn der Player gegen einen Körper läuft, der geschoben werden kann, setze dessen linearVelocity auf die Laufrichtung, flach entlang des Bodens, multipliziert mit kickPower, plus lift gerade nach oben, sodass der Ball nach vorne und oben fliegt.
  • Der Boden und der Pfosten haben keinen Rigidbody: Überspringe sie ohne Fehler.
  • Ein Ball unter den Füßen des Players wird nicht getreten.

Drücke Play und tritt gegen den roten Ball, dann Check.

Probier es selbst

using UnityEngine;

public class Kicker : MonoBehaviour
{
    public float kickPower = 6f;
    public float lift = 4f;

    // Schieße die Bälle weg, gegen die der Spieler läuft
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Echte Spiele entwickeln