Menu
CoddyTech

Dinge schieben

Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 41 von 60.

Ein CharacterController schiebt niemals etwas: Läufst du damit gegen eine Kiste mit einem Rigidbody, hält er an, als wäre dort eine Wand. Stattdessen ruft Unity für jeden Collider, den ein Move berührt, einschließlich des Bodens, OnControllerColliderHit(ControllerColliderHit hit) in den eigenen Skripten des Controllers auf, und das Skript entscheidet, was passiert. hit.collider ist das berührte Objekt, 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. Boden und 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. Bei einem Move, der steil nach unten zeigt, wurde etwas unter den Füßen berührt, und die Kiste, auf der der Spieler steht, sollte nicht weggeschoben werden.

Die Schieberichtung behält nur x und z bei, sodass eine Kiste über den Boden gleitet, anstatt in ihn hineingedrückt zu werden. Wenn du linearVelocity festlegst, statt eine Kraft hinzuzufügen, bewegen sich eine leichte und eine schwere Kiste gleich schnell; body.AddForce(pushDir * pushPower, ForceMode.Impulse) würde die schwere Kiste weniger stark schieben.

challenge icon

Aufgabe

Mittel

Lass den Spieler die Bälle wegkicken, gegen die er läuft.

  1. Schreibe in Kicker.cs void OnControllerColliderHit(ControllerColliderHit hit) und hole dir Rigidbody body = hit.collider.attachedRigidbody;.
  2. Führe return aus, wenn body null oder kinematisch ist oder wenn hit.moveDirection.y < -0.3f (ein Ball unter den Füßen).
  3. Setze body.linearVelocity auf die Laufrichtung mit y 0, multipliziert mit kickPower, plus Vector3.up * lift.

Drücke „Spielen“ und lauf gegen den roten Ball: Er fliegt nach vorne und oben. Drücke dann „Prüfen“.

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
}

Alle Lektionen in Echte Spiele entwickeln

Übe selbstständig: Unity-Playground