Menu

06 – Tutorial Intermediário – Menu Principal

E aê meus queridos indies? Prontos para mais um tutorial? Acho que estamos indo muito rápido, mas levem o tempo que acharem necessário. O post de hoje será o maior de todo o tutorial, maaaas vamos começar a aprender as novidades do Unity 5, que não vimos no 4.6, o Canvas!

O que nós vamos montar hoje é a nossa tela inicial! Ou seja, o menu e essas coisinhas. Estive olhando aqui algumas telas de menu de jogos e elas mudam bastante, cada jogo tem seu próprio estilo, alguns bem simples como é o caso de Final Fantasy, outros padronizados como é os dos RPG Makers e outros com bastante animações. Aqui tentarei fazer um meio termo, com alguns efeitos, porém nada grandioso, mas que sirva pelo menos para vocês aprenderem a usarem alguns comandos de parallax, transições, botões e salvar informações de preferências e essas coisinhas.

Então bora começar o nosso tutorial! Caso ainda não tenha salvado seu personagem agora é a hora, pois vamos deletar tudo da scene, deixando apenas a câmera (Pode dar New Scene se preferir):

01- Tutorial Menu Principal

Bom, com nossa aba Hierarchy limpa, vamos criar uma nova pasta na aba Project chamada texture dentro da pasta Resources e dentro desta pasta vamos criar uma pasta chamada backgrounds:

02- Tutorial Menu Principal

Aqui colocaremos nossas texturas que são muito parecidos com os sprites. Porém pense em um sprite como uma parte ou um desenho já pronto para ser usado, enquanto uma textura seria uma capa.

Bem, bem, agora mais uma vez vamos utilizar as imagens do site Game Art 2D:

Link para o conteúdo no Site

Link para Download 

Após baixar e extrair, procurem dentro da pasta png/BG, pelo nosso background:

BG_winter

Podem arrastar ele para dentro da pasta textures/backgrounds e alterar o nome para Background_Inverno:
03- Tutorial Menu Principal

Certifique que desta vez o conteúdo esta como Texture:

04- Tutorial Menu Principal

Bom, agora se você tentar arrastar o conteúdo para dentro da Scene ou da aba Hierarchy não deverá conseguir, porque como eu falei, uma textura seria uma espécie de capa, então vamos precisar criar um objeto que receberá um material e dizer que essa textura será aplicada a um material (Ou seja, será a capa desse material), que será usada pelo objeto (Ficou confuso? O.o).

Bom, para facilitar vamos ver na pratica. Primeiro crie uma nova pasta chamada materials (para manter o padrão em inglês das pastas, já que falamos esses nomes em inglês) :

05- Tutorial Menu Principal

Dentro dessa pasta, clique com o botão direito e procure lá embaixo por Material:

06- Tutorial Menu Principal

Aqui podemos usar o nome BackgroundInverno (Caso, repare estou usando apenas undercore _ para separar os nomes de conteúdos externos ao nosso jogo, como imagens e depois música. Tente manter um padrão próprio também):

07- Tutorial Menu Principal

Aqui iremos dizer que nosso Shader (Renderização do material) será do tipo Unlit/Texture:

08- Tutorial Menu Principal

E por fim, vamos adicionar a textura Background_Inverno ao nosso material:

09- Tutorial Menu Principal

Bem, bem, bem, agora vamos criar um objeto na nossa aba Hierarchy chamado Background:

10- Tutorial Menu Principal

Nesse objeto iremos adicionar o componente Mesh Filter (Que define a forma):

11- Tutorial Menu Principal

Aqui vamos selecionar a ultima opção: Quad (um quadro é 2D):

12- Tutorial Menu Principal

Em seguida vamos adicionar o Mesh Renderer (Que assim como o Sprite Renderer, serve para criar o conteúdo visual):

13- Tutorial Menu Principal

Ao fazer isso, já deve formar um quadrado rosa no seu cenário, correto?

14- Tutorial Menu Principal

Ele é quadrado devido ao fato de que a gente definiu que sua forma seria Quad (Caso troque, para Cone, Circle entre outras, verá o objeto mudando de forma).

Quanto ao rosa, é porque é o Material Default do Unity (Rosa é fácil de visualizar, acho que por isso que escolheram essa cor como padrão). Neste caso, temos que ir em Materials e informar que use o nosso material BackgroundInverno:

16- Tutorial Menu Principal

“Meeeu deus, como ficou pequeno!”

Verdade, então bora lá em Scale e aumentar isso ai. Nossa imagem tem a dimensão de 1800 por 893, ou seja é quase uma proporção de 1 para 2 em Y para X. Ou seja se Y for 15, X será 30:

17- Tutorial Menu Principal

Se você já souber qual é a dimensão da tela do seu jogo, pode ir ali em Free Aspect e alterar:

18- Tutorial Menu Principal

Com isso já sabe se a imagem vai estar certinha ou não na tela. Eu irei trabalhar com 16:9.

19- Tutorial Menu Principal

Interessante, né? Já temos o nosso background. Que tal adicionarmos agora umas nuvens ai?
As nuvens que irei usar são essas aqui:

Link para site das nuvens

OBS: Todo conteúdo que eu estou passando para vocês baixarem é gratuito, só precisam ver a licença se precisa ou não dá os créditos a pessoa em seus jogos.

Aqui eu alterei a imagem no photoshop para vocês, removendo o fundo e espalhando mais as nuvens, então usem essa aqui (Porém os créditos ainda são do criador original da imagem):

Nuvens

Bom, aqui o procedimento é quase o mesmo. Vamos adicionar essa imagem ao nosso Resources/textures/background com o nome Nuvens:

20- Tutorial Menu Principal

Nessa parte como nossas imagens tem fundo transparente, então é EXTREMAMENTE importante marca a opção Alpha is Transparent, senão nossa imagem vai ficar assim:

21- Tutorial Menu Principal

Com o fundo branco. Ah e não preciso dizer que ela é do tipo Texture, né?

Bom o próximo passo agora é criar um Material chamado Nuvens que será do tipo Unlit/Transparent (Se for Unlit/Textura, ele irá tentar preencher o conteúdo transparente, por isso temos que dizer que é Unlit/Transparent):

22- Tutorial Menu Principal

Mais uma vez vamos criar um novo objeto que chamaremos de Nuvens e adicionaremos os componentes Mesh Filter (Quad) e Mesh Renderer com o nosso material Nuvens:

23- Tutorial Menu Principal

Nossas nuvens estão muito pequenas no cenário, vamos aumenta-la para uma proporção de 1 para 3 (Y = 10 e X = 30):

24- Tutorial Menu Principal

Já apareceram aqui! Caso tenha achado a quantia de nuvens poucas, basta ir nas opções de Tiling do seu Material e aumentar o número em X (Quantas vezes a imagem irá se repetir horizontalmente):

25- Tutorial Menu Principal

Caso a imagem não repita e sim fique esticava, veja se a opção Wrap Mode na sua textura estar Repeat ao invés de Clamp:

26- Tutorial Menu Principal

Já está com um fundo um pouco interessante, que tal aplicar um pouco de parallax?

“Para o que?”

Parallax! Parallax nada mais é do um efeito de mover imagens de fundo e da frente em velocidades diferentes para dar uma ideia de dimensão em jogos 2D. Ou sejamos podemos mover a imagem de trás (Montanhas), mais lenta do que a nuvens, dando a impressão que a nuvens estão mais próximas do que a montanha.

Então, vamos criar um script para fazer justamente essa movimentação! Dentro da pasta Scripts vamos criar uma pasta chamada cenarios, onde podemos criar todos os scripts que vão envolver nossos cenários. Dentro dele, vou criar um script (C#) chamado de Scrolling:

27- Tutorial Menu Principal

Esse Script será bem simplesinho. Aqui basicamente teremos 2 tipos de variáveis:

Script: Scrolling.cs

    public float velocidade;        //Velocidade que a imagem irá se mover
    private Material material;       //Material do Objeto com o Script

A velocidade irá definir quão rápido o background irá se mover. Já o Material serve para a gente trabalhar as alterações do material usado no objeto.

No método Start recuperamos o material que está no Mesh Renderer:

Script: Scrolling.cs

	void Start () {
        material = GetComponent().material;
	}

E por fim no Update fazemos o movimento:

Script: Scrolling.cs

	void Update () {
        var x = Mathf.Repeat(Time.time * velocidade, 1); //Acrescendo um novo valor ao offset Horizontalmente
        var novoOffset = new Vector2(x, 0);             //Define  esse novo offset
        material.SetTextureOffset("_MainTex", novoOffset); //aplica a alteração
    }

Mathf.Repeat fará com que o valor Time.time* velocidade cresça sequencialmente em cada frame (Ou seja Time.time* velocidade desse frame + os valores dos frames anteriores), porém nunca sendo maior do que o valor que informamos no segundo parâmetro (1) e também nunca menor que zero. Seria como ele saísse de 0 e fosse subindo de pouquinho em pouquinho até que chegue em 1. Quando chega em 1, ele volta a 0 (Seria como se tivesse dado uma volta completa).

Depois que geramos o valor de X, apenas criamos uma variável com a mudança do offset (Andamos apenas o valor de X = horizontalmente). E aplicamos essa mudança através do método SetTextureOffset(“_MainText”)!

Com o Script feito, basta jogar ele agora nos objetos Background e Nuvens com velocidades diferentes:

28- Tutorial Menu Principal

29- Tutorial Menu Principal

Basta dá o play e ver a montanha e as nuvens se movendo em velocidades diferentes. E para Entender melhor, o que é esse tal de Offset. Seria como se tivéssemos girando nosso material, ou seja, quando ele chega no fim, ele recomeça do outro lado, basta observar as nuvens, que ao terminar do lado esquerdo, recomeçando do lado direito:

30- Tutorial Menu Principal

Pronto, já criamos um efeito parallax básico no fundo, vamos para agora o menu em si. Primeira coisa é criar um Panel!

Então clica com o botão direito em um canto vazio na aba Hierarchy e vai na Opção UI>>Panel:

31- Tutorial Menu Principal

Automaticamente ele vai adicionar um Canvas que é o que permite nos visualizarmos todos os componentes UI e também um Objeto EventSystem que é responsável por cuidar dos scripts de interação com os componentes UI seja no pc ou em um smartphone.

32- Tutorial Menu Principal

Outra coisa que você deve observar é que na aba Scene, os componentes UI são gigantes, porém o seu tamanho real a gente ver na aba Game:

33- Tutorial Menu Principal

Se você reduzir um pouco o tamanho desse Panel vai observar duas coisas. Que existe as bordas do Canvas na aba Scene (Considere isso a tela do jogador, ou seja o tamanho do objeto será relativo a essas bordas e não ao resto do conteúdo no cenário). A outra coisa que você vai reparar é que ao reduzir o tamanho lá na aba Scene, o nosso Panel ficou exatamente igual na aba Game:

34- Tutorial Menu Principal

Mesmo o nosso objeto Background e Nuvens sendo beeeeem menores na aba Scene, o Panel na aba Game ficou menor. Isso ocorre porque o Canvas vai se ajustar automaticamente para o tamanho da tela do jogador. Ou seja, aquelas bordas brancas na aba Scene são o equivalente as bordas da tela do jogo (Ou as bordas da tela Game). Sendo assim, se a tela do jogador muda, o Canvas se ajusta automaticamente:

35- Tutorial Menu Principal

Entenderam a relação do Canvas com a tela então? Desta forma vocês sempre vão se basear na Tela Game ou na borda da aba Scene. Se tiver background e outros componentes que não sejam UI, se baseie na aba Game.

Então agora que entendemos um pouco, podemos mudar o nome do nosso painel para PainelPrincipal:

37- Tutorial Menu Principal

Em seguida na aba Inspector temos nosso ponto de Ancoragem, que é esse quadradinho aqui:

38- Tutorial Menu Principal

Isso é algo que vocês precisam aprender bem, pois é onde está boa parte da mágica do Canvas em diferentes resoluções.

Se você clicar nele você poderá escolher qual canto da tela ele será fixo quando mudar de resoluções:

39- Tutorial Menu Principal

Ao escolher no Centro, já poderá perceber que o símbolo de ancora vai ficar no meio do Canvas:

40- Tutorial Menu Principal

O que isso significa? Significa que se por acaso, o cara tiver uma resolução que seja bem maior, esse painel vai ficar sempre no meio. Se nós colocássemos a ancora lá embaixo:

41- Tutorial Menu Principal

E a tela do jogador fosse muito maior, nosso painel sempre ia ficar na parte baixa da tela, se distanciando do meio, afinal ele irá sempre em direção do lado que ele está fixo.

Ainda não entendeu? Bom, vou deixar nosso painel quadrado, deixa-lo no meio e fixa-lo do lado esquerdo:

42- Tutorial Menu Principal

Beleza? Agora digamos que a resolução do cara seja maior que essa ai, então nosso canvas vai ficar assim:

43- Tutorial Menu Principal

Ou seja, ele continuo respeitando a distância que já existia do lado esquerdo. Agora vamos mudar a situação. Digamos que nosso objeto agora esteja com a ancora no meio.

44- Tutorial Menu Principal

Se mudarmos a resolução:

45- Tutorial Menu Principal

Ele ainda vai continuar no meio. Entenderam melhor na nova resolução?

OBS: Eu chamo de ancora, mas o nome correto disso é Pivot ou Anchor, caso queira procurar mais a respeito na internet.

Agora se você querem que o objeto não ande e sim estique, então devem escolher as opções laterais Stretch:

46- Tutorial Menu Principal

Ao mudar para uma resolução maior…

47- Tutorial Menu Principal

Se vocês conseguiram entender esses pontos, então já resolve muito dos problemas que algumas pessoas encontram com Canvas. Agora é só usufruir de cada funcionalidade dos componentes.

Então vamos voltar ao nosso trabalho. O próximo passo é baixar um conteúdo de Sprites voltado a UI (User Interface). Já sabe de onde iremos baixar né?

Link para o site
Link direto para Download

Após baixar e extrair, peço que procurem pelo conteúdo Window e o joguem dentro de uma pasta que vamos criar chamada ui dentro de sprites (Aproveitem e joguem logo o Buttons também):

48- Tutorial Menu Principal

Para ambos os casos, vamos transforma-la nas opções Sprite e Multiple (Isso a gente viu no Tutorial básico):

49- Tutorial Menu Principal

50- Tutorial Menu Principal

Ele é Multiple, porque iremos cortar essa imagem em várias outras por possuírem diversas imagens embutida. Para cortar basta ir no Sprite Editor:

51- Tutorial Menu Principal

Aqui podemos cortar manualmente ou deixar que o Unity corte automático. Vou deixar automático, pois não usaremos nada detalhado desse sprites:

52- Tutorial Menu Principal

53- Tutorial Menu Principal

Cada seleção dessas que ele fez, se tornará um novo sprite sozinho:

54- Tutorial Menu Principal

Clica no Apply lá em cima e pode fechar:

55- Tutorial Menu Principal

Repete o mesmo procedimento com o Button.

Pronto, agora vamos voltar ao nosso PainelPrincipal. Aqui podemos alterar o tamanho pelo Inspector (Os nomes vão mudar de acordo com o tipo de Pivot que você usar), mas eu recomendo ir pela própria aba Scene e olhando a aba Game como resultado:

56- Tutorial Menu Principal

Vai nessa Opção para poder alterar o tamanho de forma mais simples e depois arrasta para um tamanho que achar melhor o seu Menu:

57- Tutorial Menu Principal

Agora você deve centralizar o painel (nos Pivots), para que independente da resolução do jogador o conteúdo sempre fique no meio e o posiciona também no meio. Ai vai uma dica: Lá nos pivots, caso você aperte segurando o alt e aperte o tipo de pivot que deseja, ele posiciona o objeto automaticamente no local do pivot:

59- Tutorial Menu Principal

Prontinho!

“Mas carlos, esse negocio transparente ai é meio feio, não é não?”

Eu até que gosto, mas bora mudar para uma das nossas Windows. Então clica lá no PainelPrincipal e onde tem Image na opção Source Image, bora procurar por uma Window legalzinha. No meu caso eu curti essa Window_30 (O nome pode mudar de acordo com quantos sprites seu Unity cortou o sprite Window):

60- Tutorial Menu Principal

Porém com a transparência não ficou tão legal, ,as vocês já sabem como altera transparência, né? Né? Vai dizer que já esqueceram? Bom, então bora lá, clica em Color (Abaixo do Source Image) e altera o valor de alpha de 100 para 255:

61- Tutorial Menu Principal

62- Tutorial Menu Principal

Pronto, painel está lá sem transparência alguma!

Então próximo passo agora é criar 4 botões. Clica com o botão direito sobre o PainelPrincipal e vai em UI >> Button:

63- Tutorial Menu Principal

E altera o nome desses botões para a gente saber quem é quem:

64- Tutorial Menu Principal

Caso reparem, os botões já devem estar aparecendo (E a ideia é que sejam filhas do PainelPrincipal mesmo, pois assim, caso a gente precise mexer o PainelPrincipal, eles também vão se mexer).

65- Tutorial Menu Principal

Bom, aqui não é tão diferente, a primeira coisa que vamos fazer é mover os botões para cima e para baixo, para que não fiquem um em cima do outro:

66- Tutorial Menu Principal

Outra coisa que podemos fazer é definir suas ancoras (Que serão em relação ao objeto pai, PainelPrincipal). Aqui eu gosto de botar os botões centralizados e esticando para os lados, caso o precisemos alterar o objeto pai:

67- Tutorial Menu Principal

Exemplo:

68- Tutorial Menu Principal

Após aplicar a mesma ancoragem (Pivot) em todos os botões, podemos ir nos componente Image desses botões e alterar o Source Image (UISprite) para algo mais bonitinho:

69- Tutorial Menu Principal

70- Tutorial Menu Principal

Se ficar meio grande e feio o que provavelmente vai, basta você diminuir um pouco a largura desse botão:

71- Tutorial Menu Principal

Bom, agora é hora da gente mudar esses textos. Caso você teve a curiosidade de clicar ali na aba Hierarchy, deve ter observado que existe outro objeto chamado Text dentro dos botões:

72- Tutorial Menu Principal

É ali, onde está o texto do botão. Então ao clicar em um desses botões, basta ir na aba Inspector e trocar pelo texto correspondente:

73- Tutorial Menu Principal

A cor do texto, você pode alterar na opção Color:

74- Tutorial Menu Principal

E o tamanho da fonte em Font Size. Se quer negrito ou itálico, pode ir em Font Style. Alinhamento em Alignment e caso tenha uma fonte própria é só adicionar ao projeto e procurar ela ali em Font.

Não sabe onde pode conseguir fonte? Bom, que tal o site?

http://www.1001fonts.com/

Após achar uma fonte legal, é só baixar:

75- Tutorial Menu Principal

Após descompactar o download, crie uma pasta chamada fonts dentro da pasta Resources e arraste a sua fonte (No meu caso o Miss Issippi Demo.ttf) para lá e aplicar no seu texto:

76- Tutorial Menu Principal

Caso vocês deem play agora, já vão ver que o Unity já faz uns efeitos legais ao por o mouse por cima ou clicar no botão. Isso tudo você também pode configurar indo lá no Botão e depois no Inspector, nos comandos:

77- Tutorial Menu Principal

Highlighted Color (Ao por o mouse em cima)
Pressed Color (Ao pressionar o botão)
Disabled Color (Botão desabilitado)

Falando em Botão desabilitado, vamos desabilitar o botão CarregarJogo? Afinal, no momento não temos nenhum jogo salvo! Para desabilitar a interação, basta clicar no botão na aba Hierachy e depois na aba Inspector no Script Button desmarcar a opção Interectable:

78- Tutorial Menu Principal

E já não será mais possível interagir com esse botão. Legal, né? Depois quando a gente fizer o scirpt de Save e Load (Nova versão, mais aprimorada),a gente ativa esse botão SE tiver alguma coisa salva.

Bom, conteúdo feito, agora vamos desabilitar esse painel, porque vamos criar um novo chamado PainelConfiguracoes.

Clica no PainelPrincipal e desmarcar o checkbox de habilitado:

79- Tutorial Menu Principal

Se preferir pode copiar esse painel dando um Ctrl+C, Ctrl+V ou só Ctrl+D:

80- Tutorial Menu Principal

Vamos trocar o nome desse painel para PainelConfiguracoes, Habilita-lo e excluir esses botões:

81- Tutorial Menu Principal

Agora vamos clicar com o botão direito em cima dele e pedir para adicionar um UI >> Text que chamarei de TituloConfiguracoes:

82- Tutorial Menu Principal

83- Tutorial Menu Principal

Aqui é igual ao texto do botão, então sem novidades. Vou trocar o texto para Configurações e configurar o pivot para ficar lá no topo do menu, preso a parte superior:

84- Tutorial Menu Principal

Adicionarei também um novo botão com o nome Voltar e usando uma imagem intuitiva:

85- Tutorial Menu Principal

Não vou precisar do texto, então posso excluir o Objeto Text dentro do Botão Voltar, depois é só posiciona-lo na parte inferior da tela e ajustar seu tamanho (O Pivot, colocarei do lado esquerdo sem esticar)

86- Tutorial Menu Principal

Aqui eu não sei o que pôr nas configurações… Então vou por apenas adicionar um botão para ativar e desativar o volume e um campo de texto informando que é um volume:

88- Tutorial Menu Principal

“Pow, Carlos, como você fez tudo isso?” Não tem nada de novo, é exatamente igual ao que nós fizemos agora a pouco (UI >> Text e UI >>Button), eu sei que vocês conseguem e qualquer dúvida deixa nos comentários.

Bom. Com isso terminamos todo o nosso Layout, agora vamos dar vida a tudo isso vai Script. A primeira coisa então a fazer é desabilitar esse painel e habilitar o PainelPrincipal (Que será o painel que vai ser visto quando iniciarmos essa scene):

89- Tutorial Menu Principal

Segunda coisa a fazer é criar uma pasta em scripts chamada controllers. Dentro desta pasta vou criar o script GCMenuPrincipal (O GC vem de Game Controller, mas você não precisa por se não quiser, é apenas um padrão para organizar):

90- Tutorial Menu Principal

Bom, aqui basicamente podemos entender que cada botão será um método dentro desse GC, ou seja, vamos abrir o script e criar alguns métodos vazios e remover o Start e Update que não precisaremos agora:

Script: GCMenuPrincipal.cs

using UnityEngine;
using System.Collections;

public class GCMenuPrincipal : MonoBehaviour {

    //PainelPrincipal
    public void botaoNovoJogo() {

    }

    public void botaoCarregarJogo() {

    }

    public void botaoConfiguracoes() {

    }

    public void botaoSair() {

    }

    //PainelConfiguracoes
    public void botaoVolume() {

    }

    public void botaoVoltar() {

    }
}

Criamos um método para cada botão. Os métodos botaoNovoJogo e botaoCarregarJogo, não iremos usar esse post, pois isso é conteúdo do que vem a frente ainda, então basicamente iremos trabalhar com quatro botões: botaoConfiguracoes, botaoSair, botaoVoltar e botaoVolume.

O primeiro e mais fácil será o botaoSair, onde iremos apenas dizer para a aplicação (jogo) fechar:

Script: GCMenuPrincipal.cs

    public void botaoSair() {
        Application.Quit(); //Fecha o jogo
    }

Sim, só isso e já será o suficiente (o método Quit da classe Application, encerra o jogo), porém não vai funcionar nem aqui no Editor do Unity e nem se você exportar seu jogo para uma versão web, por motivos óbvios.

Agora vamos para o botaoConfiguracoes. Aqui a gente vai trocar de painel, então é interessante que criemos duas variáveis públicas do tipo GameObject com os nomes dos painéis:

Script: GCMenuPrincipal.cs

using UnityEngine;
using System.Collections;

public class GCMenuPrincipal : MonoBehaviour {

    public GameObject painelPrincipal;
    public GameObject painelConfiguracoes;

Pois iremos acessar esses objetos para ativa-los e desativa-los. Para modificar o painel é bem simples:

Script: GCMenuPrincipal.cs

    public void botaoConfiguracoes() {
        painelPrincipal.SetActive(false);//Desativa o Painel Principal
        painelConfiguracoes.SetActive(true); //Ativa o Painel de Configurações
    }

Como estamos saindo do painel principal para o de configurações, desativamos o painel principal e ativamos o que vamos usar. Bem simples, o SetActive é basicamente igual a clicar naquele Checkbox na aba Inspector ao lado do nome do objeto, como fizemos antes.

Bora testar? Então salve o script e depois volte ao Unity. Lá no Unity crie um novo objeto com o nome GC (Game Controller). Nele adicione o script que acabou de criar:

95- Tutorial Menu Principal

E já podemos adicionar logos os painéis aos seus respectivos campos no script GCMenuPrincipal:

96- Tutorial Menu Principal

Agora clique no botão Configuracoes que criamos na aba Hierarchy e vá na aba no final da Inspector, lá no final onde tiver On Click():

92- Tutorial Menu Principal

É aqui onde ocorre as ações ao clicar no botão. Então clique no + ali em baixo e onde tiver o None, selecione o objeto GC:

93- Tutorial Menu Principal

E reparou que ali ativou o No Function? Bom, isso que dizer que agora você pode acessar os métodos dentro de algum script que o objeto GC tenha. Então iremos selecionar o script GCMenuPrincipal e depois escolher o método botaoConfiguracoes:

94- Tutorial Menu Principal

Caso dê play, você já deve poder aperta o botão Configurações. Isso fará o painel principal desaparecer e mostrar o painel de configurações.

Com o botão voltar, é praticamente a mesma coisa, só que vamos desativar o painelConfiguracoes e ativar o painelPrincipal:

Script: GCMenuPrincipal.cs

    public void botaoVoltar() {
        painelPrincipal.SetActive(true);//Ativa o Painel Principal
        painelConfiguracoes.SetActive(false); //Desativa o Painel de Configurações
    }

Agora só falta o botaoVolume, porém aqui entrar algo que já vimos acho que no ultimo post do tutorial passado: o PlayerPrefs. Que não viu, recomendo que dê uma olhada, pois não mudou nada:

Tutorial Básico – Save e Load

E ai, já leu ao menos o inicio e já sabe para que serve ou os métodos que tem? Então bora continuar!

Basicamente o que iremos fazer aqui é verificar se quando o botão foi apertado a configuração do tipo booleana salva era false ou verdadeira. Invertemos o valor (true vira false e false vira true) e mudando a transparência do botão.

Mais precisamente a transparência daqui:

97- Tutorial Menu Principal

(Script Image do Botão)

Mas antes de mexer no método, vamos primeiro criar uma variável do tipo Image, para recuperarmos as informações desse botão:

Script: GCMenuPrincipal.cs

    public Image btVolume;

Neste momento, seu código deve estar dando um erro, dizendo que esse script Button não existe. Isso ocorre porque todo conteúdo UI, fica em um pacote diferente que temos que informar ao nosso script:

using UnityEngine.UI;

Adicione esse using UnityEngine.UI ao inicio do seu código, ficando assim:

Script: GCMenuPrincipal.cs

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GCMenuPrincipal : MonoBehaviour {

    public GameObject painelPrincipal;
    public GameObject painelConfiguracoes;
    public Image btVolume;
...

Agora beleza, já podemos trabalhar no método do botão. Caso tenha lido lá o tutorial como falei, sabe que o PlayerPrefabs armazena informações do jogo mesmo que o jogo feche, semelhante ao save. Porém ele trabalha apenas com String, Int e Float, não trabalha com variável do tipo Bool. Mas afinal de contas, o que uma variável booleana? É apenas verdadeiro e falso. E você sabe me dizer o que significa isso em binários?

1 = true
0 = false

E aqui será a mesma coisa. Então segue abaixo o nosso script:

Script: GCMenuPrincipal.cs

    public void botaoVolume() {
        var volume = PlayerPrefs.GetInt("volume");
        var color = btVolume.color;
        if (volume == 1) {
            PlayerPrefs.SetInt("volume", 0);
            color.a = 0.4f; //Alteramos o valor de alpha
        } else {
            PlayerPrefs.SetInt("volume", 1);
            color.a = 1f; //Alteramos o valor de alpha
        }
        btVolume.color = color;
    }

Vamos explicar o código agora:

var volume = PlayerPrefs.GetInt(“volume”);

Primeiro recuperamos o valor de volume, para verificar se é 1 (true) ou 0 (false).

var color = btVolume.color;

Em seguida recuperamos a coloração desse objeto, junto com o seu canal alpha (Opacidade).

if (volume == 1) {
   PlayerPrefs.SetInt(“volume”, 0);
   color.a = 0.4f; //Alteramos o valor de alpha
}

Se o volume for igual a 1 (true/verdadeiro/ativo), então salvaremos a informação que agora o volume é 0 (false/falso/desativo) e mudando a porcentagem da opacidade do botão para 40%.

else {
   PlayerPrefs.SetInt(“volume”, 1);
   color.a = 1f; //Alteramos o valor de alpha
}

Caso o volume não seja 1 (Ou seja é 0), então salvamos a informação que agora o volume estará ativo e mudamos a opacidade do botão para 100% (color.a =1f).

Por fim aplicamos a mudança dessa cor no botão:

btVolume.color = color;

Terminou? Não! Já pensou se por acaso essa for a primeira vez do jogador abrindo o jogo. Não vai existir a informação volume salva no PlayerPrefs. Sendo assim vamos usar o método Awake para fazer essa verificação e mudar a cor do objeto já para sua transparência correta:

Script: GCMenuPrincipal.cs

    void Awake() {
        if (!PlayerPrefs.HasKey("volume")) //Senão existir nenhuma informação já salva
            PlayerPrefs.SetInt("volume", 1); //Definimos o volume como ativo

        var volume = PlayerPrefs.GetInt("volume"); 
        var color = btVolume.color;
        if (volume == 1)
            color.a = 1f; //Alteramos o valor de alpha
        else
            color.a = 0.4f; //Alteramos o valor de alpha
        btVolume.color = color;
    }

Primeiro verificamos se existe alguma informação salva em relação ao volume (Usamos o método HasKey para verificar se tem valor salvo), senão já podemos salvar ele como ativo. Depois recuperamos a informação se o volume está ativo ou não, para aplicar a opacidade correta no botão, afinal se não mudarmos logo e o botão estiver desativado, ele vai aparecer como ativo antes de apertar o botão volume.

Bom, você já pode voltar para o Unity e fazer o teste, não se esqueça de informar quem é as variáveis publicas e definir as ações dos botões:

98- Tutorial Menu Principal

99- Tutorial Menu Principal

Tudo ok?

Então terminamos o tutorial? Beeeem, não acha que está faltando nada não? Certeza? Nós criamos um botão para ativar e desativar a música, mas cadê a música? Vamos adicionar então uma música ao nosso jogo?

Espera, você não é musico e não sabe compor música? Tudo bem, tem alguns sites bem bancadas com músicas livres para você usar, como é o caso do Sound Image, que fornece músicas de graças para jogos, porém vocês tem que dá os devidos créditos ao criador Eric Matyas, ok?

Sound Image Categoria Ação

Além é claro do meu amado OpenGameArt, que sempre busco sprites e texturas lá. Também possui a parte de Music e Audio com conteúdos bem bacanas.

A música que eu vou usar não é da categoria Ação e sim Dark-Ominous (Escuro-Ameaçador), que em minha opinião combina bastante com essas imagens de fundo. A música será City of Dread, segue o link abaixo:

Música City of Dread

Após baixar a música, a jogue nas pastas que iremos criar: Resources/sounds/BGM:

100- Tutorial Menu Principal

Caso reparem além de BGM, também criei outras 2 pastas (BGS e SE). O que significa cada uma?

BGM – Background Music – Músicas de fundo, trilha sonora;
BGS – Background Sound – Sons de fundo de ambientes, contínuos, como cachoeira, grilos, pássaros…
SE – Sound Effect – Efeitos de sons como ataque, dano, poder de cura, heal e por ai vai, janela quebrado, porta abrindo e por ai vai.

Esta é uma ótima forma de você separar seus áudios.

Bom, já adicionamos e agora? Agora é só adicionar essa musica em algum objeto ou criar um objeto que receba a música.

Porém há algo importante para saber. Se um objeto com a música ou efeito sonoro for colocado longe dos nossos ouvidos nós vamos escutar mais baixo, afinal é a lógica. Mas o que é os nossos ouvidos? Algum chute? Se a câmera são nossos olhos e nossos olhos são próximos dos ouvidos, então… Sim nossos ouvidos estão na câmera, mais precisamente o componente Audio Listener:

101- Tutorial Menu Principal

Então uma boa para trilha sonora em minha opinião é por o áudio junto da câmera, para ficar sempre lá tocando na mesma altura. Podemos adicionar de duas formas:

1 – Adicionando o componente Audio Source:

102- Tutorial Menu Principal

2 – Ou simplesmente arrastando o áudio da aba Project para o objeto na aba Hierarchy:

103- Tutorial Menu Principal

Em AudioClip teremos o nosso áudio:

104- Tutorial Menu Principal

A opção Mute deixa a música sem volume, Play On Awake faz com que o som toque/inicie assim que o objeto for criado e loop faz com que o som toque novamente assim que terminar. Deixamos as opções Play On Awake e Loop marcadas. Logo abaixo também temos a opção de volume se quiséssemos alterar:

105- Tutorial Menu Principal

E mais embaixo temos o 3D Sound Settings que é justamente aquilo que eu falo de quão longe vai o alcance do som.
Bom, com o áudio já adicionado, temos duas formas de ocultar. Uma seria através do Mute no componente Audio Source que já vimos e a outra é igual aos Cavaleiros do Zodiacos, destruindo nossos tímpanos de forma que não iremos escutar nada (Desabilitar o Audio Listener).

Como só criamos uma opção nas configurações de áudio, o melhor mesmo nessa situação é desabilitar o Audio Listener que poupa o trabalho de sair caçando e desabilitando diferentes tipos de áudio. Se tivéssemos feito controle de som ou diferentes opções de habilitar e desabilitar áudio para BGM, BGS e SE, ai sim seria no componente Audio Source, como ocorre em vários jogos onlines.

Então já irei criar um Script básico para a Camera chamada de GCCamera dentro da pasta scripts/controllers:

106- Tutorial Menu Principal

Dentro desse Script basicamente só vai ter dois componentes:

Script: GCCamera.cs

using UnityEngine;
using System.Collections;

public class Camera : MonoBehaviour {

    public void habilitarSom() {
        GetComponent().enabled = true;
    }

    public void desabilitarSom() {
        GetComponent().enabled = false;
    }
}

Um componente para habilitar o som e outro para desabilitar. Aqui caso reparem eu estou buscando o componente e o habilitando e desabilitando através da variável enable.

Quando estamos trabalhando com GameObject (Ou seja um objeto que está lá na aba Hierarchy), nós o habilitamos e o desabilitamos através do método SetActive, ou seja alterando ali ele fica oculto na cena. Já quando estamos trabalhando componentes do objeto como scripts, nós usamos a variável enabled, onde apenas ativa e desativa aquele componente, ok?

Bom, só assim o seu script já deveria funcionar, porém se você for gerar a versão jogável, vai ver que não funciona.
“Oxe, por que funciona no editor do Unity quando damos play e não funciona na versão compilada do jogo? O.o”.

Essa eu juro que não sei te responder, são mistérios (ou bugs do Unity). Neste caso a alternativa é ao invés de desabilitar esse Audio Listener, nós vamos baixar o volume de todo o jogo através da variável estática volume (ou pode usar o pause, se preferir). Para alterar o valor de uma variável estática não precisamos chamar uma variável do tipo da classe. Podemos alterar direto na classe:

Script: GCCamera.cs

    public void habilitarSom() {
        AudioListener.volume = 1f; //Audio do jogo em 100%
    }

    public void desabilitarSom() {
        AudioListener.volume = 0; //Audio do jogo em 0%
    }

Agora funciona tanto no editor do Unity onde fazemos os nossos testes, quando na versão que você compila para o povo jogar.

Joia, e agora por que eu fiz esses métodos ai em cima públicos? Bem, porque assim eu posso habilitar e desabilitar o som com mais facilidade ao clicar lá no botão de volume. Porém antes disso, nós iremos verificar se o áudio está ativo ou não no método Start para já habilita-lo e desabita-lo no inicio de todos os cenários:

Script: GCCamera.cs

using UnityEngine;
using System.Collections;

public class GCCamera : MonoBehaviour {

    void Start() {
        if (PlayerPrefs.GetInt("volume") == 1)
            habilitarSom();
        else
            desabilitarSom();
    }

...

“Carlos, agora pouco no GC Menu Principal você usou Awake e agora usou Start, qual eu devo usar afinal?”

Olha, os dois são bem parecidos. Ambos são usados durante a criação do objeto, porém… O Awake ele funciona antes do Start. Ou seja, no Awake é bom a gente fazer coisas que não depende de outros de outros objetos, como definir valores para o próprio script. Já no Start ele ocorre depois do Awake. Se usarmos tudo no Start pode ser que vamos tentar acessar um valor que ainda não foi definido no outro objeto, afinal o computador vai processar um Start de cada vez. Sendo assim, no primeiro (GCMenuPrincipal) eu usei Awake, para garantir que o PlayerPrefs “volume” fosse criado antes de outro script (GCCamera) tentar usa-lo no método Start. Já na câmera estou usando o Start, para ter a garantia que o PlayerPrefs já tenha sido criado para não dá erro no meu if, entendeu?

Bom, com isso pronto, caso você inicio o jogo com som ou sem som já vai funcionar. Porém ainda falta a gente habilitar e desabilitar o som ao clicar no botão. Então de volta ao script GCMenuPrincipal, vamos adicionar uma variável do tipo GCCamera chamado câmera:

Script: GCMenuPrincipal.cs

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GCMenuPrincipal : MonoBehaviour {

    public GameObject painelPrincipal;
    public GameObject painelConfiguracoes;
    public Image btVolume;
    public GCCamera camera;
...

E lá no nosso método botaoVolume, vamos habilitar e desabilitar o som:

Script: GCMenuPrincipal.cs

    public void botaoVolume() {
        var volume = PlayerPrefs.GetInt("volume");  //Recupera informação sobre o som
        var color = btVolume.color;                 //Recupera a cor do botão
        if (volume == 1) {
            PlayerPrefs.SetInt("volume", 0);    //Salva a informação do volume
            color.a = 0.4f;                     //Torna o botão mais transparente
            camera.desabilitarSom();            //Desabilita o som
        } else {
            PlayerPrefs.SetInt("volume", 1);    //Salva a informação do volume
            color.a = 1f;                       //Torna o botão 100% visivel
            camera.habilitarSom();              //Habilita o som
        }
        btVolume.color = color;
    }

Voltando ao Unity não se esqueça de dizer quem é o objeto que está com o script GCCamera:

107- Tutorial Menu Principal

Agora é só dar play e ver resultado.

Acabou? Não! Mas não fiquem com raiva de mim, só falta uma coisinha de nada para terminamos pro hoje >.<

É bem simples, vocês criar uma nova pasta chamada scenes e nela vamos salvar essa scene:

108- Tutorial Menu Principal

109- Tutorial Menu Principal

110- Tutorial Menu Principal

111- Tutorial Menu Principal

Prontinho, sempre que quiserem acessar o menu principal, basta dá dois cliques.

E com isso chegamos definitivamente ao final desse tutorial. Ele é bem fácil na realidade, só vimos algumas coisinhas de Canvas, Material e Áudio e quase nada de Script, por isso é algo que você faz sem esquentar a cabeça. Só ficou enorme, porque usei mais de 100 imagens para ilustrar esse post, mas sinceramente acho que assim fica melhor para vocês, afinal uma imagem vale mais que 1000 palavras. Os próximos tutoriais eu não vou trabalhar tanto o som, por um único motivo, o arquivo do jogo vai ficar enorme se eu por áudio em todas as scenes e objetos e aqui vocês já tiveram uma noção. No máximo terá apenas mais 4 musicas, uma para cada fase do jogo. E em alguma quarta feira ai, teremos um post extra sobre a ferramenta PixiTracker. Eu não sou músico e nem tenho dom para criar músicas, mas ao menos fica como uma ferramenta para auxiliar a vocês que quiserem criar suas próprias músicas.

Para finalizar, eu adicionei uma imagem (Botão direito UI >> Image) de título (A logo do Jogos Indie) acima do Painel para dá a impressão de título do jogo:

113- Tutorial Menu Principal

E agora depois que você fez tudo isso, eu digo que estamos em cerca de 1/5 do tutorial, então aproveite estenda todas as pastas da sua aba Project e veja o quanto você já construiu:

112- Tutorial Menu Principal

Tudo isso feito do zero e ainda não estamos nem em 20% direito do projeto. Com isso você pode ter a certeza que se o seu sonho é criar jogos, você vai conseguir chegar lá. Aposto que antes de iniciar o tutorial você não pensava em tão pouco tempo já ter feito tantas coisas assim não é mesmo? Fazer esses tutoriais é algo que cansa e ocupa bastante tempo, mas é algo recompensador olhar para trás e ver tudo o que foi feito, olhar o presente e ver o quanto vocês estão empolgados e pensar no futuro, o quão longe cada um de vocês podem chegar e podem ter certeza que no que eu puder ajudar, vocês podem contar comigo.

Valeu mesmo pessoal, até mais e um abraço ^^

Índice Tutorial Intermediário

Download do Projeto

Download do Jogo

Criador do Jogos Indie, amante de jogos, terror, música, anime e programação. Estudante de mestrado com foco em jogos na educação. Louco por Resident Evil e... sei lá, acho que é isso O.o

9 comments

  1. voçe e fodao cara mt bom oq vc faz

  2. Djalma disse:

    Cara excelente tutorial, o resultado final é muito bonito e sua explicação é muito boa.

  3. PedroPW disse:

    E ai mano bia explicação mais ta dando esse erro aki

    public void Awake(){
    if(!PlayerPrefs.HasKey(“volume”)) //se nao existir nennhuma informaçao salva
    PlayerPrefs.SetInt(“volume”, 1);

    var volume = PlayerPrefs.GetInt (“volume”);
    var color = imageBotao.color; ////AKIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

    if (volume == 1)
    color.a = 1f;
    else
    color.a = 0.4f;

    imageBotao.color = color;
    }

    erro: NullReferenceException: Object reference not set to an instance of an object

    e toda fez q aperto no botao volume aparece esse erro
    NullReferenceException: Object reference not set to an instance of an object
    MenuPrincipal.botaoVolume () (at Assets/scripts/MenuPrincipal.cs:39)
    UnityEngine.Events.InvokableCall.Invoke

    public void botaoVolume(){
    var volume = PlayerPrefs.GetInt (“volume”);
    var color = imageBotao.color; /////////////////////AKIIIIII TBM

    if (volume == 1) {
    PlayerPrefs.SetInt(“volume”, 0);
    color.a = 0.4f; //alteramos a opacidade
    camera.desabilitarSom();
    }
    else {
    PlayerPrefs.SetInt(“volume”, 1);
    color.a = 1f;
    camera.habilitarSom();
    }
    imageBotao.color = color;
    }

    valeu

    • A exceção do tipo “NullReferenceException”, indica que um determinado conteúdo é nulo, ou seja, não foi informado ou encontrado.

      O valor que está nulo é o imageBotao, por isso que sempre que você vai chama-lo dá erro. Verifique se no editor do Unity, no objeto que está com o script, lá no Inspector, se você informou que é o imageBotao. 😉

  4. Ricardo Aguillar disse:

    Carlos, estou seguindo e aprendendo muito com seus tutoriais, muito grato por isso!!
    Tenho uma dúvida, eu criei tudo da forma que vc fez, porém no GameController eu não consigo arrastar a Main Camera para a sua variável. Unity Não deixa arrastar, é como se houvesse algum erro. Por acaso sabe o que pode ser?

  5. Ricardo Aguillar disse:

    Consegui resolver. Faltou eu vincular o Script GCCamera à Main Camera. Desta forma consegui fazer o vínculo depois. Porém, o som pausa, mas depois não volta. kkk Tentando corrigir isso agora e saber onde errei.

  6. wellington disse:

    muito bom man, mais uma madrugada vendo seus tutoriais

  7. Augusto disse:

    Olá carlos!

    Como fazer o movimento de parallax do background nao só na horizontal mas tambem na vertical?
    É tipo aquelas fases do super mario que o cenario vai movendo e v c tem que correr, se tela atrás de pegar vc morre. Aí tem hora que o cenario se move para cima, tem hora que move para trás…
    o que eu posso acrescentar no script que vc fez lá em cima?

Deixe uma resposta

Parceiros

Steam Brasil LoboLimão Centro RPG Lab Indie
Mundo Gamer PodTerror

Anunciantes

Aglomerando - Agregador de conteúdo
Uêba - Os Melhores Links GeraLinks - Agregador de links Piadas Idiotas - São idiotas mas o faz rir Tedioso: Os melhores links LinkLog MeusLinks.com - Informação e conteúdo todos os dias para você! Agregador de Links - Madruga Links 4Blogs - Agregador de conteúdo Está no seu momento de descanso né? Entao clique aqui!