Menu
CoddyTech

Mira

Lezione 10 di 25 del corso Gioco Unity: Tower Defense di Coddy.

Una torre si gira per puntare al suo bersaglio: non l'intera torre, che poggia sulla sua piattaforma, ma la sua testa, un oggetto figlio che porta la canna. Girare un oggetto figlio fa ruotare tutto ciò che si trova sotto di esso e lascia invariato il genitore.

I nemici camminano più in basso rispetto alle teste, quindi la direzione da una testa al suo nemico punta leggermente verso il basso, e una testa che la seguisse guardando dritto si inclinerebbe in avanti. Impostare y della direzione su 0 la mantiene orizzontale, così la testa ruota solo attorno all'asse verticale. La lampada di un faro che segue una nave:

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction) è la rotazione che punta in quella direzione, quindi la lampada si orienta subito verso la nave. Invece, la testa di una torre dovrebbe girare a una certa velocità: Quaternion.RotateTowards(from, to, maxDegrees) del capitolo Rotazione ruota al massimo di maxDegrees, e la velocità di rotazione in gradi al secondo moltiplicata per Time.deltaTime fornisce la quota di rotazione di ogni fotogramma.
challenge icon

Sfida

Medio

Ruota la testa di ogni torre per puntare al suo bersaglio.

  1. In Tower, aggiungi [SerializeField] private Transform head; e [SerializeField] private float turnSpeed = 270f;.
  2. Quando c'è un bersaglio, ruota head verso di esso solo attorno all'asse y, al massimo di turnSpeed * Time.deltaTime gradi, usando Quaternion.RotateTowards.
  3. Spara dalla canna: head.position + head.forward * 0.6f.

Premi «Gioca»: le teste seguono i nemici e sparano dalla canna. Poi premi «Verifica».

Provalo tu

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);
    }
}

Tutte le lezioni di Gioco Unity: Tower Defense

Esercitati da solo: Playground Unity