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.Sfida
MedioRuota la testa di ogni torre per puntare al suo bersaglio.
- In
Tower, aggiungi[SerializeField] private Transform head;e[SerializeField] private float turnSpeed = 270f;. - Quando c'è un bersaglio, ruota
headverso di esso solo attorno all'asse y, al massimo diturnSpeed * Time.deltaTimegradi, usandoQuaternion.RotateTowards. - 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