Menu
CoddyTech

Zielen

Lektion 10 von 25 im Kurs Unity-Spiel: Tower Defense von Coddy.

Ein Turm dreht sich zu seinem Ziel: nicht der ganze Turm, der auf seiner Plattform steht, sondern sein Kopf, ein untergeordnetes Objekt, das den Lauf trägt. Wenn sich ein untergeordnetes Objekt dreht, dreht sich alles unter ihm mit, während das übergeordnete Objekt unverändert bleibt.

Die Gegner bewegen sich tiefer als die Köpfe, daher zeigt die Richtung vom Kopf zu seinem Gegner ein wenig nach unten, und ein Kopf, der direkt dorthin blicken würde, würde sich nach vorne neigen. Wenn du den Wert y der Richtung auf 0 setzt, bleibt sie waagerecht, sodass sich der Kopf nur um die vertikale Achse dreht. Eine Leuchtturmlampe, die einem Schiff folgt:

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction) ist die Drehung, die in diese Richtung blickt, sodass sich die Lampe sofort zum Schiff dreht. Ein Turmkopf sollte sich stattdessen mit einer bestimmten Geschwindigkeit drehen: Quaternion.RotateTowards(from, to, maxDegrees) aus dem Kapitel „Drehungen“ dreht sich um höchstens maxDegrees, und eine Drehgeschwindigkeit in Grad pro Sekunde multipliziert mit Time.deltaTime ergibt den Anteil für jeden Frame.

challenge icon

Aufgabe

Mittel

Drehe den Kopf jedes Turms so, dass er auf sein Ziel zeigt.

  1. Füge in Tower [SerializeField] private Transform head; und [SerializeField] private float turnSpeed = 270f; hinzu.
  2. Wenn ein Ziel vorhanden ist, drehe head nur um die y-Achse darauf zu, und zwar um höchstens turnSpeed * Time.deltaTime Grad, mit Quaternion.RotateTowards.
  3. Schieße aus dem Lauf: head.position + head.forward * 0.6f.

Drücke „Spielen“: Die Köpfe folgen den Gegnern und schießen aus dem Lauf. Drücke dann „Prüfen“.

Probier es selbst

using UnityEngine;

public class Tower : MonoBehaviour
{
    public float range = 4f;
    public int damage = 2;
    [SerializeField] private Projectile projectilePrefab;

    private Enemy target;
    private float nextShot;

    void Update()
    {
        Enemy found = FindTarget();
        if (found != null && found != target)
        {
            Debug.Log("Target: " + found.name);
        }
        target = found;
        if (target == null)
        {
            return;
        }

        if (Time.time >= nextShot)
        {
            Fire();
            nextShot = Time.time + 1f;
        }
    }

    Enemy FindTarget()
    {
        Enemy nearest = null;
        float nearestDistance = range;
        foreach (Enemy enemy in Enemy.All)
        {
            float distance = Vector3.Distance(transform.position, enemy.transform.position);
            if (distance <= nearestDistance)
            {
                nearest = enemy;
                nearestDistance = distance;
            }
        }
        return nearest;
    }

    void Fire()
    {
        Projectile shot = Instantiate(projectilePrefab, transform.position + Vector3.up, Quaternion.identity);
        shot.Launch(target.transform, damage);
    }
}

Alle Lektionen in Unity-Spiel: Tower Defense

Übe selbstständig: Unity-Playground