Desenvolvimento de jogos com Unity e C#: introdução para web devs

1. Por que Unity para desenvolvedores web?

Desenvolvedores web que decidem migrar para o desenvolvimento de jogos com frequência encontram na Unity um ambiente familiar e ao mesmo tempo desafiador. A principal diferença está no paradigma: enquanto o desenvolvimento web lida com páginas renderizadas por navegadores, a Unity trabalha com cenas tridimensionais interativas em tempo real.

Paradigma visual vs. paradigma de código: O Editor Unity é uma ferramenta visual onde você arrasta objetos, ajusta propriedades em painéis e vê o resultado instantaneamente. Isso contrasta com o workflow web, onde você escreve HTML/CSS e atualiza o navegador. Na Unity, você pode posicionar uma câmera, adicionar luzes e criar terreno sem escrever uma linha de código.

Diferenças fundamentais: Uma página web é estática até que o JavaScript a modifique. Uma cena de jogo é um loop contínuo que atualiza posições, verifica colisões e processa entrada do usuário a 60 quadros por segundo. O conceito de requestAnimationFrame no JavaScript é uma versão simplificada do loop de jogo da Unity.

Ecossistema Unity: A Asset Store oferece milhares de assets prontos (modelos 3D, sons, scripts), a documentação oficial é extensa, e a comunidade ativa produz tutoriais diariamente. Para o web dev, isso equivale a ter npm, MDN e Stack Overflow em um só lugar, mas com foco em jogos.

2. Configurando o ambiente: do navegador para a engine

A instalação começa pelo Unity Hub, que gerencia versões do Editor e projetos. Recomenda-se a versão LTS (Long Term Support) mais recente para estabilidade.

Estrutura de projeto: Um projeto Unity contém pastas como Assets (onde tudo fica), Scenes (arquivos de cena), Scripts (código C#) e Prefabs (objetos reutilizáveis). Diferente do desenvolvimento web, não há node_modules ou package.json — os assets são importados diretamente para a pasta Assets.

Primeira cena: Ao criar uma nova cena, você encontra:
- GameObject: a unidade básica, equivalente a uma div no HTML
- Transform: componente obrigatório que define posição, rotação e escala (x, y, z)
- Câmera: o olho do jogador, similar à viewport do navegador

// Exemplo: Criando um cubo via script
using UnityEngine;

public class CriadorDeObjetos : MonoBehaviour
{
    void Start()
    {
        GameObject cubo = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cubo.transform.position = new Vector3(0, 1, 0);
        cubo.transform.localScale = new Vector3(2, 2, 2);
    }
}

3. C# para web devs: o que muda e o que fica igual

Se você conhece JavaScript ou TypeScript, o C# será relativamente familiar. A sintaxe básica (loops, condicionais, funções) é quase idêntica.

Similaridades com JavaScript/TypeScript:

// JavaScript
function saudacao(nome) {
    return "Olá, " + nome;
}

// C#
string Saudacao(string nome) {
    return "Olá, " + nome;
}

Diferenças cruciais:
- Tipagem forte: Em C#, toda variável tem tipo definido em tempo de compilação. int vida = 100; não pode receber string depois.
- Namespaces: Equivalente aos módulos do ES6, mas com sintaxe using UnityEngine; no topo do arquivo.
- Compilação: C# é compilado para IL (Intermediate Language) antes de executar, enquanto JavaScript é interpretado. Isso significa que erros de tipo são capturados antes de rodar o jogo.

MonoBehaviour: Toda classe que controla um GameObject herda de MonoBehaviour. Isso é similar a estender uma classe base, como React.Component no React.

using UnityEngine;

public class MeuPrimeiroScript : MonoBehaviour
{
    public float velocidade = 5f;

    void Start() { /* Executado uma vez ao iniciar */ }
    void Update() { /* Executado a cada frame */ }
}

4. Criando o primeiro script: do HTML/CSS para o comportamento

O script MonoBehaviour possui métodos especiais que formam o ciclo de vida do objeto:

  • Awake(): Executado antes de qualquer outro método, ideal para inicializar variáveis
  • Start(): Executado no primeiro frame ativo, após Awake
  • Update(): Executado a cada frame, onde a lógica principal do jogo acontece

Acessando componentes: Para modificar um GameObject, você precisa acessar seus componentes via GetComponent<T>() ou expor referências públicas no Inspector.

using UnityEngine;

public class MovimentoBasico : MonoBehaviour
{
    public float velocidade = 10f;

    void Update()
    {
        // Input.GetAxis retorna valor entre -1 e 1
        float movimentoHorizontal = Input.GetAxis("Horizontal");
        float movimentoVertical = Input.GetAxis("Vertical");

        Vector3 direcao = new Vector3(movimentoHorizontal, 0, movimentoVertical);

        // Time.deltaTime garante movimento independente de FPS
        transform.Translate(direcao * velocidade * Time.deltaTime);
    }
}

Comparação com web: Em uma página web, você faria element.style.left = x + "px" no evento de tecla. Na Unity, você manipula o Transform diretamente no Update, e o motor gráfico cuida da renderização.

5. Física e colisões: substituindo o DOM por Rigidbody

No desenvolvimento web, interações são baseadas em eventos de clique, hover ou drag. Na Unity, a física é simulada com componentes específicos.

Rigidbody e Collider:
- Rigidbody: Adiciona física ao GameObject (gravidade, massa, velocidade)
- Collider: Define o volume de colisão (Box, Sphere, Mesh)

using UnityEngine;

public class Coletor : MonoBehaviour
{
    void OnCollisionEnter(Collision colisao)
    {
        if (colisao.gameObject.CompareTag("Coletavel"))
        {
            Destroy(colisao.gameObject);
            Debug.Log("Item coletado!");
        }
    }

    void OnTriggerEnter(Collider other)
    {
        // Trigger não causa colisão física, apenas detecta entrada
        if (other.CompareTag("Checkpoint"))
        {
            Debug.Log("Checkpoint atingido!");
        }
    }
}

Comparação com web: Em vez de element.addEventListener('click', handler), você usa OnCollisionEnter para detectar contato físico. A diferença: colisões consideram velocidade, ângulo e massa, enquanto eventos DOM são binários (clicou/não clicou).

6. Interface do usuário (UI): do HTML/React para Canvas

O sistema Canvas da Unity é poderoso e lembra o CSS Flexbox. Elementos de UI usam RectTransform, que permite ancoragem relativa ao pai.

Criando UI básica:

using UnityEngine;
using UnityEngine.UI;

public class GerenciadorUI : MonoBehaviour
{
    public Text textoPontuacao;
    public Button botaoReiniciar;
    private int pontuacao = 0;

    void Start()
    {
        botaoReiniciar.onClick.AddListener(ReiniciarJogo);
        AtualizarTexto();
    }

    void AtualizarTexto()
    {
        textoPontuacao.text = "Pontuação: " + pontuacao;
    }

    void ReiniciarJogo()
    {
        pontuacao = 0;
        AtualizarTexto();
    }
}

Ancoragem: Similar ao position: relative e position: absolute do CSS, mas visual. Você ancora elementos aos cantos ou centros do Canvas, e eles se redimensionam automaticamente.

7. Gerenciamento de estado e ciclo de vida do jogo

Assim como React usa Redux ou Context API, a Unity gerencia estado global com padrões como Singleton e GameManager.

Padrão Singleton:

public class GameManager : MonoBehaviour
{
    public static GameManager Instancia { get; private set; }
    public int vidas = 3;
    public int pontuacao = 0;

    void Awake()
    {
        if (Instancia == null)
        {
            Instancia = this;
            DontDestroyOnLoad(gameObject); // Persiste entre cenas
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void PerderVida()
    {
        vidas--;
        if (vidas <= 0) CarregarGameOver();
    }
}

Gerenciamento de cenas: SceneManager.LoadScene("Fase2") carrega uma nova cena, similar a navegar para outra rota em uma SPA. DontDestroyOnLoad mantém objetos entre cenas, como o GameManager.

8. Publicação e próximos passos

A Unity permite build para múltiplas plataformas. Para web devs, o build WebGL é o mais natural — gera HTML, JS e WASM que rodam no navegador.

Configurações de build:
- WebGL: Marque "Development Build" para testes locais
- Compression: Use Gzip para reduzir tamanho
- Player Settings: Configure resolução, ícone e nome da empresa

Publicação:
- itch.io: Plataforma indie, gratuita, aceita builds WebGL
- WebGL no navegador: Hospede os arquivos em qualquer servidor estático (Netlify, Vercel)
- Steam: Para jogos comerciais, requer build nativo (Windows, Mac, Linux)

Recursos para aprofundamento:
- Complete o Unity Junior Programmer Pathway
- Estude o código fonte de jogos open source na Unity
- Pratique com game jams (Ludum Dare, Global Game Jam)


Referências