Apuntar
Lección 10 de 25 del curso Juego de Unity: Defensa de torres de Coddy.
Una torre gira para mirar a su objetivo: no toda la torre, que permanece sobre su plataforma, sino su cabeza, un objeto secundario que lleva el cañón. Al girar un objeto secundario, gira todo lo que hay debajo de él, mientras que el objeto principal permanece igual.
Los enemigos caminan más abajo que las cabezas, así que la dirección desde una cabeza hasta su enemigo apunta un poco hacia abajo, y una cabeza que mirara directamente en esa dirección se inclinaría hacia delante. Establecer en 0 la y de la dirección la mantiene nivelada, así que la cabeza solo gira alrededor del eje vertical. La lámpara de un faro que sigue a un barco:
Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);Quaternion.LookRotation(direction) es la rotación que apunta en esa dirección, así que la lámpara se orienta hacia el barco de inmediato. En cambio, la cabeza de una torre debería girar a cierta velocidad: Quaternion.RotateTowards(from, to, maxDegrees), del capítulo sobre rotación, gira como máximo maxDegrees, y una velocidad de giro en grados por segundo multiplicada por Time.deltaTime da la parte correspondiente a cada fotograma.Desafío
IntermedioGira la cabeza de cada torre para que apunte a su objetivo.
- En
Tower, añade[SerializeField] private Transform head;y[SerializeField] private float turnSpeed = 270f;. - Cuando haya un objetivo, gira
headhacia él solo alrededor del eje y, como máximoturnSpeed * Time.deltaTimegrados, conQuaternion.RotateTowards. - Dispara desde el cañón:
head.position + head.forward * 0.6f.
Pulsa «Jugar»: las cabezas siguen a los enemigos y disparan desde el cañón. Después, pulsa «Comprobar».
Pruébalo tú mismo
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);
}
}
Todas las lecciones de Juego de Unity: Defensa de torres
Practica por tu cuenta: Playground de Unity