Mire
Lição 10 de 25 do curso Jogo de Unity: Defesa de Torres da Coddy.
Uma torre se vira para encarar seu alvo: não a torre inteira, que fica sobre sua base, mas sua cabeça, um objeto filho que carrega o cano. Girar um objeto filho gira tudo que está abaixo dele e deixa o objeto pai como está.
Os inimigos andam mais abaixo que as cabeças, então a direção de uma cabeça até seu inimigo aponta um pouco para baixo, e uma cabeça que olhasse diretamente nessa direção se inclinaria para a frente. Definir o y da direção como 0 a mantém nivelada, então a cabeça gira apenas em torno do eixo vertical. Uma lâmpada de farol que acompanha um navio:
Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);Quaternion.LookRotation(direction) é a rotação que fica voltada para essa direção, então a lâmpada se vira para o navio de uma só vez. Já a cabeça de uma torre deve girar a uma certa velocidade: Quaternion.RotateTowards(from, to, maxDegrees), do capítulo sobre rotação, gira no máximo maxDegrees, e a velocidade de giro em graus por segundo multiplicada por Time.deltaTime fornece a parcela de cada quadro.Desafio
MédioGire a cabeça de cada torre para mirar em seu alvo.
- Em
Tower, adicione[SerializeField] private Transform head;e[SerializeField] private float turnSpeed = 270f;. - Quando houver um alvo, gire
headem direção a ele somente em torno do eixo y, no máximoturnSpeed * Time.deltaTimegraus, comQuaternion.RotateTowards. - Dispare do cano:
head.position + head.forward * 0.6f.
Pressione “Jogar”: as cabeças acompanham os inimigos e disparam do cano. Em seguida, clique em “Verificar”.
Experimente você mesmo
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 as lições de Jogo de Unity: Defesa de Torres
Pratique por conta própria: Playground de Unity