Unity3D: Uma cena, várias câmeras

Vitor Navarro
Codando a vida adoidado
4 min readMay 9, 2018

--

Uma das coisas bacanas nos jogos, principalmente os de corrida, é ter mais de uma opção de câmera com visões diferentes e até mesmo enxergando novos objetos, texturas, cores.

Existem vários tipos de ciclo de câmera, mas o que vou atacar aqui é um básico que já é caminho para resolver jogos de corrida e reposicionamento genérico da câmera.

TLDR: Ei tem certeza que não prefere ler? Se você só quer o script clica aqui

Passo 1: Criando a cena

Crie um projeto no Unity ou uma nova cena se quiser usar um projeto existente.

Dentro da cena tenha:

  1. Câmera
  2. Caso seja uma cena vazia adicione um objeto para ponto de referência, ex: box.
  3. Game objects vazios para representar novas posições de câmera, quantos forem necessários. Dêem nomes decentes para não se perder, ex: posição fora, posição dentro, posição sob ombro.

Dica: Eu costumo usar nomenclatura toda em inglês, isso ajuda na prática da lingua e na hora de buscar ajuda em fóruns.

Passo 2: O SCRIPT

Existem duas formas dessa idéia funcionar, uma delas é o script ficar na câmera que será alterada, a outra é o script aceitar a câmera como propriedade. Eu segui com o script fazendo parte da câmera, assim podemos pensar em coisas como split-screen com jogadores mudando suas câmeras individualmente mais facilmente.

Crie um script, eu dei o nome no meu de VNCameraSwitch, e adicione-o a sua câmera.

Começando: posição inicial

Vamos precisar ter acesso aos game objects de posições, mas não precisamos do GameObject em si mas sim do seu Transform.

Além dele teremos a posição atual e vamos guardar também a tecla usada para trocar entre as câmeras. Escolhi o número 2 no teclado númerico perto dos F's, porque? Porque 2 lembra base dois 😎.

public class VNCameraSwitch : MonoBehaviour {

public Transform[] positions;
public int currentPosition = 0;
public KeyCode switchKey = KeyCode.Alpha2;

Dica: Deixar as variáveis públicas faz com que elas fiquem disponíveis na UI do Unity para serem modificadas no objeto da cena.

Assim que o script rodar precisamos colocar a câmera na posição inicial caso exista alguma posição a ser utilizada. Vamos alterar diretamente o position e rotation do transform da câmera com a posição atual (currentPosition).

private void SetCameraInitialPosition() {
if (positions.Length > 0) {
updateCameraPosition ();
}
}
void updateCameraPosition() {
transform.rotation = positions[currentPosition].rotation;
transform.position = positions[currentPosition].position;
}
void Start()
{
SetCameraInitialPosition ();
}

Com isso se adicionarmos os game objects na lista de posições e rodarmos a cena o script já vai posicionar a câmera no primeiro local.

Sequência: fazendo um ciclo com as posições

Agora vamos usar o Update do script para mudar entre as posições, é um ciclo então andamos nas posições começando da atual e indo até a última posição na lista de 1 em 1.

Dica: Uma alternativa seria atribuir uma câmera para uma determinada tecla e ao invés de ciclo trocar de acordo com a tecla.

void Update()
{
if (Input.GetKeyUp (switchKey) && if (isEqualsToCameraPosition (positions[currentPosition])) {
currentPosition++;
currentPosition = currentPosition % positions.Length;
updateCameraPosition ();
}
}

Eita pera ai que diabos é isso: currentPosition = currentPosition % positions.Length;?

O operador modulo (mod), representado pelo sinal %, pega o resto da divisão de dois números. Como as listas vão de 0 até Length-1, então quando um número chegar em Length e for divido por ele mesmo a posição reseta para 0.

Outra coisa que não fizemos ainda foi esse método isEqualsToCameraPosition. O que ele faz? Ele verifica se o transform é igual a posição que deveria ser a atual, fazemos isso pois assim só trocamos de posição quando realmente a câmera está onde deveria, vai ser ainda mais útil logo menos.

bool isEqualsToCameraPosition(Transform currentPosition) {
return transform.position == currentPosition.position &&
transform.rotation == currentPosition.rotation;
}

Se rodar agora você conseguirá ver a câmera mudar entre as posições a cada toque na tecla.

Gif de ciclo de câmera com 3 posições.

O bônus: animando entre câmeras

Tudo muito bonito mas muito seco. É possível animar a câmera indo de um ponto a outro, para isso vamos precisar alterar um pouquinho a posição antiga em direção a desejada posição atual. Esse pouquinho vamos chamar de speed e essa variável será modificada em função do tempo do update, isso evita problemas entre velocidades diferentes entre computadores pontentes e menos potentes.

public float speed = 20f;
public animate = true;

Adicionemos um novo método que vai usar a velocidade e jogar a posição atual da câmera um pouco mais próxima da posição desejada.

void IncrementPosition () {
// O Time.deltaTime é o intervalo entre
float delta = speed * Time.deltaTime;
Transform endPosition = positions [currentPosition];
// Podemos usar o Lerp ou MoveTowards o resultado é o mesmo, andar o vetor atual um pouco mais próximo de seu vetor destino
Vector3 nextPosition = Vector3.MoveTowards (transform.position, endPosition.position, delta);
Quaternion nextRotation = Quaternion.RotateTowards(transform.rotation, endPosition.rotation, delta);
// Atualizamos a posição da câmera
transform.position = nextPosition;
transform.rotation = nextRotation;
}

O IncrementPosition deve ser usado no Update logo após o if do Input. Aproveite e cancele o updateCameraPosition se estiver usando o modo animado.

void Update() {        
if (Input.GetKeyUp (switchKey) && isEqualsToCameraPosition (positions[currentPosition])) {
currentPosition++;
currentPosition = currentPosition % positions.Length;
if (!useAnimation) {
updateCameraPosition ();
}
}

if (useAnimation && !isEqualsToCameraPosition (positions [currentPosition])) {
IncrementPosition ();
}
}

Porque não consigo mudar de câmera no meio da animação? Lembra que o isEqualsToCameraPositio ia ser útil? Propositalmente só permitimos a mudança quando a câmera está na posição exata de onde deveria, e isso acontece apenas no fim da animação.

A partir de hoje suas câmeras vâo ficar muito mais interessantes. E aí fez diferente? Adicionou algo? Conte-nos sua experiência com câmeras no Unity nos comentários.

--

--

Vitor Navarro
Codando a vida adoidado

Hi I’m software engineer / game developer, technology enthusiast that loves books, games and being with friends amongst other things.