Menu
CoddyTech

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.
challenge icon

Desafio

Médio

Gire a cabeça de cada torre para mirar em seu alvo.

  1. Em Tower, adicione [SerializeField] private Transform head; e [SerializeField] private float turnSpeed = 270f;.
  2. Quando houver um alvo, gire head em direção a ele somente em torno do eixo y, no máximo turnSpeed * Time.deltaTime graus, com Quaternion.RotateTowards.
  3. 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