Menu

Tutorial de Unity 2D #11 – Áudio

Chegando ao tutorial de número 11, onde vamos aprender a adicionar áudio no nosso jogo, para não deixa-lo tão monótono.

Como de costume, o primeiro passo que vou pedir para que vocês é que baixem os seguintes áudios e sprites:
stage.mp3
magic.wav
sword_swipe.mp3

OBS: Clique com o botão direito nos links acima e escolha Salvar Link Como…

Caso deseje outra música ou efeito e não sabe onde baixar, pode tentar procurar um através deste link:

http://www.gamethemesongs.com/ (músicas de jogos)

http://www.freesfx.co.uk/ (Efeitos)

O que iremos fazer hoje é bem simples com os áudios:

1 – O áudio stage.mp3 ficará tocando na nossa fase. (Pode ser habilidade e desabilitado clicando no botão com as imagens acima);

2 – magic.wav será o áudio que tocará durante a animação do ataque do Ghost;

3 – sword_swipe.mp3 será o áudio tocando durante o ataque do Skeleton;

Tudo bem simples. Resumundo é uma música tocando no fundo e alguns efeitos.

Então vamos começar a mexer no Unity! A primeira coisa que eu vou pedir é que vocês criem duas novas pastas no Unity, “bgm” e “se”:

Quando falamos em imagens temos os conjuntos texture e sprite. Quando falamos em áudio, possuímos os seguintes conjuntos:

BGM (Background Music) – Música tocando no fundo do jogo (No nosso caso é o stage.mp3)

SE (Sound Effect) – Efeitos de sons como vidro quebrando, sons de bala, fogo, socos… (No nosso caso é o ataque dos monstros: magic.wav e sword_swipe.mp3)

ME (Music Effect) – São as músicas tocadas em alguns momentos específicos (Um pouco diferente da música de fundo), como usar item ou upar de level sendo uma música ao invés de um simples som. (Não usaremos nesse projeto)

BGS (Background Sound) – São os sons que ficam tocando no fundo do cenário, por exemplo, grilos em uma floresta, chuvas, trovões, gritos (Constante no fundo do cenário)…. (Também não teremos no nosso projeto)

Com as pastas criadas, insira o stage.mp3 na pasta bgm; magic.wav e sword_swipe.mp3,na pasta se; e sound_off.png e sound_on.png na pasta texture.

Pronto, agora vamos conhecer um pequeno conceito sobre os áudios no Unity. Todos nós para escutarmos um som, precisamos dos nossos ouvidos correto? No jogo não é diferente, ele também vai precisar de “ouvidos” para escutar os sons do jogo e estes “ouvidos” por padrão já vem na câmera do nosso jogo. Ele é o Audio Listener dentro do Main Camera:

Se você remover, este componente simplesmente você não vai escutar mais som algum, a menos que você adicione novamente o Audio Listener através de Add Component >> Audio >> Audio Listener.

Os nossos “ouvidos” no Unity ficam na câmera, pois é ela que é a nossa visão como jogador e como ela sempre anda junto ao personagem, significa dizer que quando chegamos perto de uma fonte de som, iremos escutar mais alto do que se estivermos longe desta fonte de som. Se a nossa câmera fosse fixa e apenas o personagem movesse, não faria muito sentido deixar o nosso “ouvido” na câmera não é mesmo? Para esta situação iriamos tirar o Audio Listener da câmera e adiciona ao objeto Player, mas este não é o nosso caso.

Bom, já entendemos como escutamos dentro do jogo, agora se você clicar no áudio stage.mp3 inserido e ver as suas opções no Inspector, vai ver algo chamado 3D Sound. Esse 3D sound é o responsável por fazermos escutar mais alto ou baixo dependendo da distância do que está causando o som. Como essa música irá tocar no fundo, eu vou pedir para que vocês desmarquem, assim ela vai virar um 2D Sound, o que significa que vai ser a mesma altura independente do Audio Listener estar perto ou longe da fonte do som.

Agora vamos criar um Objeto chamado Musica

E adicionar o GUITexture nele com a textura sound_on.png.

Vocês se lembram do porquê estamos usando um GUITexture ao invés de Sprite Renderer? Já vimos isso em aulas passadas, mas para relembra-los, usamos Sprite Render quando o Objeto faz parte do cenário e GUITexture quando o Objeto faz parte da visão do jogador (Acompanha a câmera), e neste caso esse será um botão para ativar e desativar a música de fundo.

Após cria-lo, ajuste o seu tamanho (scale) e posição para ficar no canto superior da tela (position):

Agora é a hora de adicionar o áudio stage.mp3 para ele. Clique novamente sobre o objeto Musica e na aba Inspector adicione um Audio Source:

Em Audio Clip escolha a música stage.mp3.

Também deixe as opções Play On Awake (Tocar assim que o objeto for criado, ou seja, no inicio da cena) e Loop (Repetir assim que acabar) selecionados.

Se a música estiver alta, você pode ajustar na opção Volume:

Com a música de fundo criada, vamos criar agora um script para deixar mudo ou não a musica! Para isso crie um script (C# Script) chamado Musica.
Nele teremos três propriedades:

public Texture2D musicOn; 
public Texture2D musicOff; 
public bool ativo;

O Texture2D é novo para vocês, mas não é nada de complicado. Aqui apenas jogaremos as texturas ao invés de objetos. Ou seja, vamos informar qual é a imagem da música ativa e a imagem da música no mudo. O “ativo”, serve apenas para a gente verificar se a música está ligada ou não.
No update, vamos adicionar as seguintes linhas:

if (ativo) {
		gameObject.audio.mute = false;
		gameObject.guiTexture.texture = musicOn;
	} else {
		gameObject.audio.mute = true;
		gameObject.guiTexture.texture = musicOff;
	}

Aqui estamos dizendo que SE a música estiver ativa ENTÃO, o aúdio do nosso objeto não estará mudo e a textura do GUITexture será a que definirmos em musicOn.

Caso a música não esteja ativa, então o áudio estará no mudo e a textura do GUITexture será a que definirmos para musicOff.

Para finalizar esse script, vamos apenas adicionar uma ação, que quando o mouse clicar no objeto, ele mude o status do ativo. Se tiver ativo for true, vai virar false e se for false vai virar true:

void OnMouseDown() {
		ativo = !ativo;
}

Pronto, agora é só voltar para o nosso objeto Musica no Unity e adicionar o script. Deixe a opção ativo marcada e coloque as imagens dentro dos atributos Music On e Music Off.

(Ignorem a pasta sprites, eu coloquei os conteúdos lá e nem me toquei, a pasta correta é texture)

Caso você der o play, a música já vai tocar. Se você clicar na caixa de som no topo, ela mudará de status e deixará de tocar a música, porém o nosso personagem também vai soltar seu ataque especial.

Para evitar esse conflito, vamos remover o botão alternativo do Fire1 nas opções do Input. (Edit >> Project Settings >> Input):

Após remover o Alt Positive Button, este problema estará resolvido.

Agora vamos adicionar os SE (Sound Effects) dos nossos ataques. Isto será uma tarefa bem simples, para ser sincero.

Clique sobre o prefab do Skeleton e adicione um componente do tipo Audio Source com o Audio Clip sword_swipe.mp3:

Desmarque a opção Play On Awake, pois neste caso seremos nós via script que iremos informar quando tocar o áudio.

Pronto, agora no script do Skeleton no método OnCollisionEnter2D, vamos adicionar uma única e simples linha dentro da condição que verifica se o objeto que colidiu tem a Tag Player, ou seja, a mesma condição que ativa a animação do ataque do Skeleton.

void OnCollisionEnter2D(Collision2D colisor) {
		if (colisor.gameObject.tag == "Player") {
			gameObject.audio.Play();
			animator.SetTrigger("atacou");

			var player = colisor.gameObject.transform.GetComponent();
			player.PerdeVida(30);

			colisor.gameObject.transform.Translate(-Vector2.right);
		}
}		

A linha adicionada foi a gameObject.audio.Play();, onde apenas dizemos para tocar o áudio. Simples assim.

Agora vamos fazer o mesmo com o Ghost, clique no prefab do Ghost e adicione um componente do tipo Audio Source (Add Component >> Audio >> Audio Source) com o áudio magic.wav e a opção Play On Awake desmarcada.

Agora no Script de Ghost, antes ou depois de chamarmos a animação pelo Trigger “atacou”, vamos fazer tocar o áudio:

void Update () {
		var distancia = (player.transform.position.x - transform.position.x);
		if (distancia > 0) {
			transform.eulerAngles = new Vector2(0, 0);
		} else {
			transform.eulerAngles = new Vector2(0, 180);
		}

		if (!atacou && Mathf.Abs(distancia) <= distanciaAtaque) {
 			gameObject.audio.Play ();
 			animator.SetTrigger("atacou");
 			Instantiate(ataque, transform.position, transform.rotation);
 			atacou = true;
 		}
 		if (atacou) {
 			contagemIntervalo += Time.deltaTime;
 			if (contagemIntervalo >= intervaloAtaque) {
				atacou = false;
				contagemIntervalo = 0;
			}
		}
	}

Pronto, com isso o nosso tutorial de áudio está pronto. Vocês aprenderam a diferença entre o áudio 2D e 3D. Aprenderam sobre os “ouvidos” (Audio Listener), os tipos de áudio (BGM, BGS, SE, ME), como deixar uma música no fundo repetindo sem parar, como chamar um áudio na hora desejada (Método Play), como deixar um áudio mudo (Para parar use o Stop(), mas ai ela irá iniciar do começo quando der o Play(), o mudo continua como se não a música não tivesse parado e o Pause() vai parar a música, mas quando der Play() continua de onde parou).

Espero que tenham gostado. Agora só faltam 2 tutoriais, para vocês completarem o seu primeiro jogo em Unity!
Dúvidas, criticas ou sugestões já sabem o que fazer 😉

Musica.cs

using UnityEngine;
using System.Collections;

public class Musica : MonoBehaviour {

	public Texture2D musicOn; 
	public Texture2D musicOff; 
	public bool ativo;

	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		if (ativo) {
			gameObject.audio.mute = false;
			gameObject.guiTexture.texture = musicOn;
		} else {
			gameObject.audio.mute = true;
			gameObject.guiTexture.texture = musicOff;
		}
	}

	void OnMouseDown() {
		ativo = !ativo;
	}

}

Skeleton.cs

using UnityEngine;
using System.Collections;

public class Skeleton : MonoBehaviour {

	public float velocidade;
	public bool direcao;
	public float duracaoDirecao;

	private float tempoNaDirecao;
	private Animator animator; 

	// Use this for initialization
	void Start () {
		animator = gameObject.transform.GetComponent ();
	}
	
	// Update is called once per frame
	void Update () {

		if (direcao) {
			transform.eulerAngles = new Vector2(0, 0);
		} else {
			transform.eulerAngles = new Vector2(0, 180);
		}
		transform.Translate(Vector2.right * velocidade * Time.deltaTime);

		tempoNaDirecao += Time.deltaTime;
		if (tempoNaDirecao >= duracaoDirecao) {
			tempoNaDirecao = 0;
			direcao = !direcao;
		}
 	}

	void OnCollisionEnter2D(Collision2D colisor) {
		if (colisor.gameObject.tag == "Player") {
			gameObject.audio.Play();
			animator.SetTrigger("atacou");

			var player = colisor.gameObject.transform.GetComponent();
			player.PerdeVida(30);

			colisor.gameObject.transform.Translate(-Vector2.right);

		}
	}
}

Ghost.cs

using UnityEngine;
using System.Collections;

public class Ghost : MonoBehaviour {

	public float intervaloAtaque;
	private float contagemIntervalo;
	private bool atacou;
	public float distanciaAtaque;
	
	public GameObject ataque;
	public GameObject player;

	private Animator animator;

	// Use this for initialization
	void Start () {
		animator = gameObject.transform.GetComponent ();
	}
	
	// Update is called once per frame
	void Update () {
		var distancia = (player.transform.position.x - transform.position.x);
		if (distancia > 0) {
			transform.eulerAngles = new Vector2(0, 0);
		} else {
			transform.eulerAngles = new Vector2(0, 180);
		}

		if (!atacou && Mathf.Abs(distancia) <= distanciaAtaque) {
 			gameObject.audio.Play ();
 			animator.SetTrigger("atacou");
 			Instantiate(ataque, transform.position, transform.rotation);
 			atacou = true;
 		}
 		if (atacou) {
 			contagemIntervalo += Time.deltaTime;
 			if (contagemIntervalo >= intervaloAtaque) {
				atacou = false;
				contagemIntervalo = 0;
			}
		}
	}
}

Parte 10 – Ataque Especial
Indice Unity 2D
Parte 12 – Mudar de Fase

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

29 comments

  1. Victor Hugo disse:

    muito bom =D

  2. Marcos Cruz disse:

    Show! ! ! com os audios no jogo, o jogo ganha outra cara, ficou muito foda! vlw Carlos, com sua incrivel ajuda acho que muitos que acompanha suas aulas estão finalizando seus jogos xD

    Muito Obrigado! mesmo fera e ancioso pra aprender, mudar de fase.

  3. Silva disse:

    Continua tudo massa!!

  4. Karfann Nacif disse:

    ae fico bao hein!! vlw d novo Carlos!

  5. Antonio disse:

    Excelentes esses tutoriais!! Segui todos eles e estão muito bons mesmo! Obrigado!

    No jogo que estou fazendo, coloquei um som quando o meu personagem colide com uma moeda para ganhar pontos (aquele som tipico de jogos como super mario) e o som não é reproduzido porque me da o seguinte erro/aviso “Can not play a disable audio source”.
    Ele esta dando este erro porque no momento da colisao o objeto é destruido e ele nao reproduz o som.

    Sabe como resolver esse problema?

    Obrigado!

    • Bom antonio, eu vou lhe dá duas escolhas.

      A primeira:
      renderer.enabled = false; //desabilita a visão da moeda
      Destroy (gameObject, 1f); //bota para ele ser destruído daqui a 1 segundo, para dá tempo de tocar o som

      Segunda:
      Ao invés de setar o áudio no Unity, faço isso no script (MonoDevelop). Adicione o atributo:

      public AudioClip audio;

      e antes de destruir o objeto faça isso:
      AudioSource.PlayClipAtPoint(audio, Vector3.zero);
      Destroy (gameObject);

      Ele vai criar um novo objeto, para tocar o áudio. Assim que o áudio acabar ele irá destruí-lo.

      Ah, lembrando que depois deverá dizer qual é o audio utilizado no atributo audio no Unity.

  6. Gabriel disse:

    Eai carlos..Estou seguindo seus tutoriais, que sao muito bons por sinal, mas tive um problema…Quando eu estou no unity testando o jogo e sem ele estar maximizado, fica tudo certinho, mas quando eu maximizo ele ou jogo após fazer o build, o menu principal (que fiz seguindo o tutorial de fases que vc fez) fica totalmente fora de posição, e as textures do audio ficam extremamente grandes…O que posso fazer pra tentar arrumar isso? pra nao importar a resolução que eu use, tudo estar no lugar certo e do tamanho proporcional ao que deveria estar…
    Aliás, parabéns pelos tutoriais, me ajudaram muito!

  7. Opa, hahahaha
    Estou de novo aqui com outro “bug” novamente no script. Por enquanto é no script “Musica”.
    Aparentemente o Unity não está reconhecendo o “mute” e o “texture”.

    O Unity mandou a seguinte mensagem:
    ‘UnityEngine.Component’ não contém uma definição para ‘mute’ e não foi possível encontrar nenhum método de extensão ‘mute’ que aceite um primeiro argumento de tipo ‘UnityEngine.Component’ (está a faltar uma directiva using ou uma referência à assemblagem?)

    O mesmo ocorre com o ‘texture’.

    O erro acontece no void Update:
    void Update () {
    if (ativo) {
    gameObject.audio.mute = false;
    gameObject.guiTexture.texture = musicOn;
    } else {
    gameObject.audio.mute = true;
    gameObject.guiTexture.texture = musicOff;

  8. Pode deixar XD
    O programa se “auto corrigiu”

    Ele mudou automaticamente o código para:

    void Update () {
    if (ativo) {
    gameObject.GetComponent().mute = false;
    gameObject.GetComponent().texture = musicOn;
    } else {
    gameObject.GetComponent().mute = true;
    gameObject.GetComponent().texture = musicOff;
    }
    }

    E parou de dar erro desta parte.

  9. Aparentemente o Unity não está reconhecendo o “mute” e o “texture”.
    O Unity mandou a seguinte mensagem:
    ‘UnityEngine.Component’ não contém uma definição para ‘mute’ e não foi possível encontrar nenhum método de extensão ‘mute’ que aceite um primeiro argumento de tipo ‘UnityEngine.Component’ (está a faltar uma directiva using ou uma referência à assemblagem?)
    O mesmo ocorre com o ‘texture’.
    O erro acontece no void Update:
    void Update () {
    if (ativo) {
    gameObject.audio.mute = false;
    gameObject.guiTexture.texture = musicOn;
    } else {
    gameObject.audio.mute = true;
    gameObject.guiTexture.texture = musicOff;

    mas no meu caso, o programa não corrigiu.

    • Opa Rodrigo. Você deve estar usando o Unity 5

      Então não é possível acessar esses dois componentes direto. É preciso busca-los antes:

      gameObject.GetComponent<AudioSource>().mute = false
      gameObject.GetComponent<GUITexture>().texture = novaTextura

  10. Mesmo mudando o código, aparece essa mensagem:

    Error The type arguments for method ‘UnityEngine.GameObject.GetComponent()’ cannot be inferred from the usage. Try specifying the type arguments explicitly.

    • Ops, esquecei que o < e o > o WordPress considera tag e oculta o conteúdo. Pronto!
      gameObject.GetComponent<AudioSource>().mute = false
      gameObject.GetComponent<GUITexture>().texture = novaTextura

  11. Código não funciona, fala que o “void” é inesperedo (unexpected symbol “void”)

    • Qual parte que apresenta o void?

      E quanto a atualizar o código, infelizmente não vou fazer não, pois já tem um novo tutorial com a nova versão do Unity onde eu trato essas informações já atualizadas ^^

  12. Railson disse:

    Está dando esse erro:
    Severity Code Description Project File Line Suppression State
    Error CS0619 ‘GameObject.audio’ is obsolete: ‘Property audio has been deprecated. Use GetComponent() instead. (UnityUpgradable)’ Geometry War – Facebook.CSharp 20 Active
    Estou usando a versão 5.4.2f2 da Unity, sabe como é agora nessa nova versão?

  13. Railson disse:

    Deixa pra lá, consegui resolver kkkk vlw

  14. amigo muito obrigado pelo tutorial.
    Por favor me ajudar pois o audio da minha colisão só executa se eu marcar Play on Awake… assim nao fica perfeito e não consigo corrigir…

  15. Pode deixar amigo, consegui resolver! Obrigado!!

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!