REFIT-DOC // NAVINHA2026
NAVINHA2026 // MANUAL DE REFIT
Guia passo a passo para modernizar a nave: sair do código legado (Input Manager antigo) e instalar os novos sistemas de bordo — Input System, Cinemachine 3 e Camera Shake.
🎮 Input System
🎥 Cinemachine 3+
💥 Camera Shake
📋 Briefing da missão
Antes de sair reescrevendo tudo, precisamos entender o que muda e por quê. O projeto atual funciona com o sistema de Input antigo (Input.GetAxis) e não tem câmera dinâmica nem sistema de munição. A missão de hoje é modernizar 4 sistemas da nave:
Preparar o estaleiro (backup + Unity 6)
Nunca faça cirurgia numa nave sem ter uma cópia de segurança dela. Sempre.
Faça um backup do projeto
Feche o Unity. Copie a pasta inteira do Navinha2026 para outro lugar (pendrive, nuvem, outra pasta) e renomeie para algo como Navinha2026_BACKUP. Se algo der errado, você volta no tempo sem drama.
Instale o Unity 6 (ou mais novo) pelo Unity Hub
Abra o Unity Hub → Installs → Install Editor e escolha a versão Unity 6000.x LTS (ou mais recente). Marque os módulos de build da sua plataforma (ex: Windows/WebGL).
Abra o projeto com o novo Editor
No Hub, clique nos 3 pontinhos ao lado do projeto → Change Editor Version → selecione a versão do Unity 6. O Unity vai avisar que vai converter o projeto — confirme.
Player.cs.
Instalar os novos sistemas (pacotes)
Input System e Cinemachine não vêm ativados por padrão — são “peças” que a gente encaixa via Package Manager.
Abra o Package Manager
Menu Window → Package Manager. No topo, troque o filtro de “In Project” para Unity Registry — é a “loja oficial” de pacotes da Unity.
Instale o pacote “Input System”
Pesquise por Input System na lista, clique nele e depois em Install. O Unity vai perguntar se quer reiniciar o Editor para ativar o novo sistema — clique em Yes.
Instale o pacote “Cinemachine”
Ainda no Package Manager, pesquise Cinemachine e instale. No Unity 6, a versão instalada já é a Cinemachine 3.x — a que vamos usar (repare que os nomes dos componentes mudaram em relação à versão 2, isso é importante mais pra frente).
Ative o novo sistema de Input no Player Settings
Vá em Edit → Project Settings → Player → Other Settings. Procure o campo Active Input Handling e mude de Input Manager (Old) para Input System Package (New).
Input.GetAxis, que só existe no sistema antigo. É esperado dar erro no Console agora — vamos reescrever esse script no Módulo 04. Não se desespere!
Criar o mapa de controles (Input Actions)
Sem o componente Player Input — vamos ler os controles direto no código, do jeito “profissional”.
Crie o arquivo de ações
No painel Project, clique com o botão direito dentro de Assets/Input/ (crie essa pasta se não existir) → Create → Input Actions. Nomeie o arquivo de NavinhaControls.
Abra o editor de ações e crie o Action Map
Dê duplo clique no arquivo NavinhaControls.inputactions. Na coluna da esquerda (“Action Maps”), clique no + e crie um mapa chamado Nave. Um Action Map é só um “grupo” de controles — tipo um painel de botões dedicado à nave.
Crie as 4 ações da nave
Dentro do Action Map Nave, clique no + na coluna “Actions” quatro vezes e configure assim:
| Ação | Action Type | Control Type | Binding sugerido |
|---|---|---|---|
| Mirar | Value | Vector 2 | <Mouse>/position |
| Acelerar | Button | Button | <Mouse>/leftButton |
| Frear | Button | Button | <Mouse>/rightButton |
| Atirar | Button | Button | <Keyboard>/space |
Para trocar o “Action Type” e o binding, clique na ação e use o painel Properties/Action à direita. Para adicionar o binding, clique no + ao lado da ação → Add Binding, depois clique em “Listen” e aperte a tecla/botão desejado.
<Keyboard>/w e em Frear para <Keyboard>/s. Clique com o botão direito na ação → Add Binding de novo.Gere a classe C# (sem usar o componente Player Input!)
Clique no arquivo NavinhaControls.inputactions no painel Project (uma vez, para selecionar — não abrir). No Inspector, marque a caixinha Generate C# Class. Deixe o nome da classe como NavinhaControls e clique em Apply.
Isso cria um script gerado automaticamente que representa seu mapa de controles como uma classe C# comum — é essa classe que vamos instanciar direto no Player.cs, sem precisar arrastar nenhum componente no Inspector.
Salve o Save Asset
Clique em Save Asset no canto superior esquerdo da janela do Input Actions e feche a janela.
Reescrever o Player.cs
Aqui entram as duas mudanças de mecânica: nave que acelera/freia na direção do mouse, e munição limitada.
Apague o conteúdo antigo do Player.cs e cole o novo código
Abra Assets/Script/Player.cs e substitua tudo por este código. Leia os comentários — eles explicam cada bloco:
using UnityEngine; using UnityEngine.InputSystem; using Unity.Cinemachine; [RequireComponent(typeof(Rigidbody2D))] public class Player : MonoBehaviour { [Header("Movimento")] public float aceleracao = 8f; // força aplicada ao acelerar public float velocidadeMaxima = 6f; // limite de velocidade da nave public float frenagem = 4f; // quão rápido a velocidade cai ao frear public float velocidadeRotacao = 720f; // graus/seg. de giro pra mirar no mouse [Header("Referências")] public Camera cameraDoJogo; [Header("Tiro")] public GameObject laser; public Transform disparo; public AudioSource somLaser; public int disparosMaximos = 5; // "pente" de tiros (3 a 5, ajuste no Inspector) public float tempoRecarga = 1.5f; // segundos para recuperar 1 disparo [Header("Camera Shake")] public CinemachineImpulseSource fonteDeImpacto; // dispara o tremor de câmera int disparosAtuais; float timerRecarga; Rigidbody2D rig; Vector2 direcaoMira; bool estaAcelerando; bool estaFreando; NavinhaControls controles; // classe gerada pelo Input Actions (Módulo 03) void Awake() { rig = GetComponent<Rigidbody2D>(); controles = new NavinhaControls(); } void OnEnable() { // "Enable" liga o mapa de controles — sem isso, os inputs não são lidos controles.Nave.Enable(); controles.Nave.Atirar.performed += Disparar; } void OnDisable() { // sempre desliga junto — evita erros quando o objeto é destruído controles.Nave.Atirar.performed -= Disparar; controles.Nave.Disable(); } void Start() { somLaser = GetComponent<AudioSource>(); disparosAtuais = disparosMaximos; } void Update() { LerInput(); RecarregarMunicao(); } void FixedUpdate() { // física sempre no FixedUpdate, pra ficar suave e independente de FPS Mirar(); Mover(); } void LerInput() { estaAcelerando = controles.Nave.Acelerar.IsPressed(); estaFreando = controles.Nave.Frear.IsPressed(); } void Mirar() { Vector2 posicaoMouseTela = controles.Nave.Mirar.ReadValue<Vector2>(); Vector2 posicaoMouseMundo = cameraDoJogo.ScreenToWorldPoint(posicaoMouseTela); direcaoMira = (posicaoMouseMundo - rig.position).normalized; float anguloAlvo = Mathf.Atan2(direcaoMira.y, direcaoMira.x) * Mathf.Rad2Deg; // MoveTowardsAngle gira suavemente até o ângulo alvo, em vez de "teletransportar" a rotação float anguloSuave = Mathf.MoveTowardsAngle(rig.rotation, anguloAlvo, velocidadeRotacao * Time.fixedDeltaTime); rig.MoveRotation(anguloSuave); } void Mover() { if (estaAcelerando) { // empurra a nave na direção que ela está mirando (o mouse) rig.linearVelocity += direcaoMira * aceleracao * Time.fixedDeltaTime; rig.linearVelocity = Vector2.ClampMagnitude(rig.linearVelocity, velocidadeMaxima); } else if (estaFreando) { // reduz a velocidade aos poucos até zero — freio, não parada brusca rig.linearVelocity = Vector2.MoveTowards(rig.linearVelocity, Vector2.zero, frenagem * Time.fixedDeltaTime); } // se nenhum botão estiver pressionado, a nave mantém a velocidade (inércia espacial) } void Disparar(InputAction.CallbackContext contexto) { if (disparosAtuais <= 0) return; // sem munição, sem tiro Instantiate(laser, disparo.position, disparo.rotation); somLaser.Play(); disparosAtuais--; } void RecarregarMunicao() { if (disparosAtuais >= disparosMaximos) return; timerRecarga += Time.deltaTime; if (timerRecarga >= tempoRecarga) { disparosAtuais++; timerRecarga = 0f; } } void OnTriggerEnter2D(Collider2D bateu) { // mantém o "teleporte" nas bordas da tela, igual o original if (bateu.gameObject.CompareTag("x")) transform.position = new Vector3(transform.position.x * -0.9f, transform.position.y, transform.position.z); if (bateu.gameObject.CompareTag("y")) transform.position = new Vector3(transform.position.x, transform.position.y * -0.9f, transform.position.z); } void OnCollisionEnter2D(Collision2D colisao) { if (colisao.gameObject.CompareTag("Asteroid")) { // dispara o pulso que o Impulse Listener da câmera vai "sentir" fonteDeImpacto?.GenerateImpulse(); } } }
Entenda o que mudou (recap rápido)
- Mira: em vez de girar com base no eixo Horizontal/Vertical, a nave sempre aponta pra onde o mouse está.
- Acelerar: aplica força na direção da mira, com um teto de velocidade (
velocidadeMaxima). - Frear: não zera a velocidade instantaneamente — usa
MoveTowardspra reduzir aos poucos, taxa controlada porfrenagem. - Tiro: só dispara se
disparosAtuais > 0. A cadatempoRecargasegundos, recupera 1 tiro (até o máximo). - Sem Player Input: a leitura dos controles é 100% feita chamando os métodos da classe
NavinhaControlsgerada no Módulo 03 — nenhum componente extra no Inspector.
Configure o Tag “Asteroid”
Selecione o prefab Assets/Prefabs/Asteroid (ou o objeto na cena), e no topo do Inspector, no campo Tag, clique em Add Tag se ainda não existir, crie a tag Asteroid e aplique nesse objeto. É essa tag que o novo OnCollisionEnter2D usa pra saber quando a nave foi atingida.
Instalar a câmera Cinemachine 3
Trocando a câmera fixa por uma câmera “viva”, pronta pra reagir ao jogo.
Crie a Cinemachine Camera
Menu GameObject → Cinemachine → Cinemachine Camera. Isso cria um objeto novo na Hierarchy (algo como CM Camera) e automaticamente adiciona um Cinemachine Brain na sua Main Camera — é o Brain que traduz o que a Cinemachine Camera “pensa” para a câmera real que renderiza a tela.
Configure o enquadramento
Selecione a CM Camera. Como o jogo é 2D com câmera fixa olhando para o campo de asteroides, você pode deixar o campo Follow vazio (câmera parada) ou arrastar o Player para acompanhar a nave — teste os dois e veja qual funciona melhor pro seu jogo.
Remova scripts de câmera antigos (se existirem)
Se a Main Camera original tinha algum script de movimento manual, desative ou remova — agora quem manda na câmera é a Cinemachine.
Camera Shake ao ser atingido
O tremor de câmera usa o sistema de “Impulse” da Cinemachine — um emissor (na nave) e um ouvinte (na câmera).
Adicione o Impulse Listener na câmera
Selecione a CM Camera criada no módulo anterior → Add Component → procure Cinemachine Impulse Listener e adicione.
Adicione o Impulse Source na nave
Selecione o objeto Player → Add Component → Cinemachine Impulse Source. Ajuste o campo Impulse Definition → Impulse Shape para algo curto e brusco (o padrão “Bump” funciona bem para impacto de asteroide).
Conecte no Inspector do Player
Ainda com o Player selecionado, olhe o script Player no Inspector. Arraste o próprio objeto Player (ou o componente Impulse Source dele) para o campo Fonte De Impacto.
?. no código pra evitar erro), mas o shake simplesmente não vai acontecer. Sempre confira essa referência.Ajuste a intensidade (opcional, mas recomendado)
No componente Cinemachine Impulse Listener da câmera, existe um campo Gain — aumente para um tremor mais forte, diminua para algo sutil. Teste em Play até achar o “tapa na tela” ideal, sem exagerar a ponto de atrapalhar a leitura do jogo.
Ajustes finais na cena
Últimos parafusos antes do lançamento.
Confira as referências no Inspector do Player
- Camera Do Jogo → arraste a câmera real (a que tem o Cinemachine Brain, geralmente a Main Camera).
- Laser → o prefab do tiro (já existente).
- Disparo → o Transform de onde o tiro nasce (já existente).
- Fonte De Impacto → o Impulse Source, configurado no Módulo 06.
- Disparos Maximos → defina 3 ou 5, como preferir para o balanceamento do jogo.
O Laser.cs não precisa mudar
Repare que Laser.cs já tinha a variável tempoDeVida, que destrói o tiro automaticamente depois de alguns segundos (Destroy(this.gameObject, tempoDeVida)). Ou seja, o requisito de “tiro com tempo de vida” já estava pronto — só faltava limitar a quantidade, o que resolvemos no Player.cs.
Rigidbody2D do Player
No componente Rigidbody2D do Player, mude Gravity Scale para 0 (se ainda não estiver) e deixe Linear Drag em 0, já que agora quem controla a desaceleração é o nosso próprio script de frenagem, não o drag da física.
Checklist de teste final
Aperte Play e confira, um por um:
- ✅ A nave gira suavemente para acompanhar o mouse, mesmo parada.
- ✅ Segurando o botão de Acelerar, a nave ganha velocidade na direção do ponteiro, até o limite máximo.
- ✅ Segurando Frear, a velocidade cai aos poucos — não trava de uma vez.
- ✅ Soltando os dois botões, a nave mantém a velocidade atual (inércia).
- ✅ Apertando Atirar, o tiro sai e o contador de munição diminui.
- ✅ Depois de gastar toda a munição, o botão de atirar não faz nada até recarregar.
- ✅ Ao colidir com um asteroide, a câmera treme por um instante.
- ✅ Nenhum erro vermelho aparece no Console.


Deixe um comentário