Menu

Tutorial de Unity 2D #9 – Inimigo parte 2

Continuando ao nosso Tutorial de Unity 2D, vamos adicionar o segundo inimigo!

Este tutorial é uma continuação direta do da semana passada, então caso não o tenha visto, recomendo que o faça, pois as partes iguais eu não vou detalhar, apenas dizer o que vocês têm que fazer e me focar na parte diferente do tutorial da semana passada, ok? (Afinal, se eu for detalhar tudo de novo, vai ser praticamente o mesmo tutorial da semana passada e esta não é a ideia).

Lembram-se dos dois outros sprites que eu pedi para vocês adicionarem na semana passada? Bom, se não fizeram é hora de adiciona-los agora:

sprite_ghost

sprite_blue_flame

Não se lembram como adiciona? Então a primeira coisa a fazer é baixar a imagem para o seu computador e depois na pasta sprites, clique com o botão direito e escolha Import New Assets…

01 - Inimigo 2 - Import

Após colocar os dois lá, vou pedir que realizem os seguintes passos:
01 – Criem um novo objeto chamado Ghost;

02 - Inimigo 2 - Create Object

03 - Inimigos 2 - Ghost

02 – no sprite_ghost, trocar o Texture Mode para Sprite ou Sprite (2D\uGUI) e o Sprite Mode para Multiple;

04 - Inimigos 2 - Sprite Mode

03 – Realizar o Slice da imagem:

05 - Inimigos 2 - Slice

04 – Adicionar no Objeto Ghost o componente Sprite Renderer com o Sprite do Ghost:

06 - Inimigos 2 - Sprite Renderer

07 - Inimigos 2 - Sprite Ghost

05 – Adicionar o Circle Collider 2D (Não terá Rigidbody2D, nosso inimigo voará):

08 - Inimigos 2 - Circle Collider

06 – Clicar no objeto Ghost e depois na Aba Animation. Nela adicionar os 4 sprites superiores do ghost (Salvar a animação dentro da pasta animation/ghost com o nome ghost_parado):

Nesta parte também se deve mudar o sample para 10, e se quiser adicione novamente os 4 sprites, porém alterando a ordem do key frame ficando:

Sprite_ghost_0
Sprite_ghost_1
Sprite_ghost_2
Sprite_ghost_3
Sprite_ghost_3
Sprite_ghost_2
Sprite_ghost_1
Sprite_ghost_0

09 - Inimigos 2 - Key Frames

07 – Criar uma nova animação chamada ghost_atacando, usando os 3 sprites inferiores e trocando o sample para 10:

10 - Inimigos 2 - Create new Clip

11 - Inimigos 2 - Animation Atacando

08 – Na Aba Animator criar o parâmetro “atacou” como Trigger:

12 - Inimigos 2 - Parametro

09 – Criar uma transição de ghost_parado para ghost_atacando com conditions “atacou” e uma transição de ghost_atacando para ghost_parado com condição Exit Time = 1.00.

13 - Inimigos 2 - Transicao 1

14 - Inimigos 2 - Condicao 1

———

15 - Inimigos 2 - Transicao 2

16 - Inimigos 2 - Condicao 2

10 – Adicionar no nosso objeto Ghost a Tag Inimigo:

17 - Inimigos 2 - Tag Inimigo

11 – na animação de ghost_atacando desabilitar a opção de Loop:

18 - Inimigos 2 - Desabilitar loop

12 – Criar um objeto chamado ChamasAzuis:

02 - Inimigo 2 - Create Object

19 - Inimigos 2 - ChamasAzuis

13 – no Sprite sprite_blue_flame, mudar sua Texture para Sprite e o Sprite Mode para Multiple;

20 - Inimigos 2 - Sprite Mode

14 – Realizar o Slice do sprite_blue_flame, de forma que todas as bolas de fogo tenham a mesma altura e cuidado com alguns pequenos cortes que podem aparecer. Caso tenha aparecido no seu slice automático, os exclua para ficar apenas as bolas de fogo:

21 - Inimigos 2 - Slice

15 – No objeto ChamasAzuis adicionar um componente Sprite Renderer com o Sprite do sprite_blue_flame;

22 - Inimigos 2 - Sprite Renderer

16 – Adicionar um Circle Collider 2D;

23 - Inimigos 2 - Circle Collider 2D

17 – Na aba Animations com o ChamasAzuis selecionado, jogue os demais sprites da chama azul, para cria sua animação (Salve em animations\chamas_azuis com o nome chamas_azuis);

24 - Inimigos 2 - animation chamas azuis

Pronto, realizado essas etapas que já fizemos algumas (Ou inúmeras) vezes em outros tutoriais vamos para o que é de novo.

A primeira coisa é o script da bola de fogo azul, então peço que vão na pasta scripts com o botão direito e criem um C# Script (Create >> C# Script) chamado ChamasAzuis.

Abra o Script no MonoDevelop e adicione as seguintes propriedades:

public float velocidade;
public int dano;

Onde velocidade vai determinar a velocidade que ela vai caminhar e o dano será o dano causado ao herói.
No método Start vamos informar que o objeto será destruído após 5 segundos:

void Start () {
	Destroy (gameObject, 5f);
}

No método Update, vamos fazer o movimento dessa bola de fogo:

void Update () {
transform.Translate (Vector2.right * velocidade * Time.deltaTime);
}

Agora vamos criar um método de colisão para quando a bola de fogo tocar em algo se auto destruir e se esse objeto for o player, vamos causa-lhe um dano.

void OnCollisionEnter2D(Collision2D colisor) {
	if (colisor.gameObject.tag == "Player") {
		var player = colisor.gameObject.transform.GetComponent();
		player.PerdeVida(dano);
	}
	Destroy(gameObject);
}

Nada do outro mundo, só coisas que já estamos acostumados não é mesmo? Agora adicione esse script no Objeto ChamasAzuis no Unity, adicione a velocidade, dano e crie um Prefab para ele.

25 - Inimigos 2 - Script

26 - Inimigos 2 - Prefab

Com o ataque pronto, só falta criar o script do inimigo. Para isso crie um novo script na pasta Scripts chamado Ghost.
No nosso script vamos adicionar as seguintes propriedades:

public float intervaloAtaque;
private float contagemIntervalo;
private bool atacou;
public float distanciaAtaque;

public GameObject ataque;
public GameObject player;

private Animator animator;

contagemIntervalo – é o tempo que terá entre um ataque e outro (cooldown do ataque).
contagemIntervalo – se o inimigo acabou de atacar é esse o atributo que irá verificar a contagem.
ataque – Será o objeto ChamasAzuis.
player – nosso personagem principal.
animator – ficará responsável pela troca das animações do Ghost.

Podemos já no método Start setar o valor do animator:

void Start () {
	animator = gameObject.transform.GetComponent ();
}

Como nosso personagem ficará parado, o que teremos que nos preocupar é que ele esteja virado para o lado do nosso herói. Como vamos fazer isso então?

Não consegue pensar como? Nós só vamos precisar saber onde o nosso herói está no nosso eixo X. Imagine a seguinte situação, nosso personagem está na posição 1 e logo a sua frente na posição 3 está o inimigo.

Personagem (1) —– Inimigo (3)

Se subtraímos a posição do herói com a posição do inimigo teremos:

1 – 3 = -2

Logo se o resultado for negative, significa que o inimigo está na frente do herói (lado direito).

Agora vamos imaginar o contrário, o herói acabou de passar o inimigo:

Inimigo (3) —– Personagem (4)

4 – 3 = 1

Obtemos um valor positivo, ou seja, o inimigo está atrás do personagem (lado esquerdo). Pronto já sabemos para qual lado virar o nosso inimigo dependendo da posição do herói. Agora só precisamos verificar se essa distância está dentro do limite que queremos para ele realizar um ataque. Com isso o nosso script Update ficará assim:

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) {
		animator.SetTrigger("atacou");
		Instantiate(ataque, transform.position, transform.rotation);
		atacou = true;
	}
}

var distancia = (player.transform.position.x - transform.position.x);

Aqui só pegamos a distância entre o personagem e o inimigo, como vimos antes.

if (distancia > 0) {
        transform.eulerAngles = new Vector2(0, 0);
} else {
        transform.eulerAngles = new Vector2(0, 180);
}

Nesta parte viramos o inimigo para o lado do personagem através da análise da distância se for positiva ou negativa.

if (!atacou && Mathf.Abs(distancia) <= distanciaAtaque) {    
        animator.SetTrigger("atacou");
        Instantiate(ataque, transform.position, transform.rotation);
        atacou = true;
}

Se o personagem não tiver realizado um ataque e a distância absoluta dele for menos do que você definiu para ele realizar o ataque, ele irá invocar uma bola de fogo para acertar o Player.

Por que o valor absoluto? Imagine a situação em que você definiu que quando a distância entre eles fossem menor de 1 ponto, o inimigo soltaria o ataque. Se o player estiver na posição 1 e o inimigo na posição 2, a distância entre eles será 1, logo ele realizará o ataque.

Porém se o player estiver na posição 0 e o inimigo na posição 2, a distância deles será de 2 pontos, porém a subtração dá -2 (0 - 2 = -2), por isso que nesta ocasião temos que pegar o valor absoluto, do contrário sempre que o personagem estiver do lado esquerdo do inimigo, esse valor será negativo e consequentemente menor que a distância que você definiu.

Se você for executar agora, o inimigo já estará funcionando, porém ele só realiza um único ataque e nunca mais atacará de novo, então temos que fazer a contagem para ele poder realizar outro ataque após completar o intervalo.

Então atualize o seu Update para:

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) {
 		animator.SetTrigger("atacou");
 		Instantiate(ataque, transform.position, transform.rotation);
 		atacou = true;
 	}
 	if (atacou) {
 		contagemIntervalo += Time.deltaTime;
 		if (contagemIntervalo >= intervaloAtaque) {
			atacou = false;
			contagemIntervalo = 0;
		}
	}
}

if (atacou) {
        contagemIntervalo += Time.deltaTime;
        if (contagemIntervalo >= intervaloAtaque) {
                atacou = false;
                contagemIntervalo = 0;
        }
}

Se o inimigo atacou vamos ter uma contagem (O cooldown de alguns jogos) para que ele possa atacar novamente. E após essa contagem, ele poderá atacar novamente (atacou = false).

Pronto, agora é só voltar ao Unity, setar o script no Ghost com os dados do script:

27 - Inimigos 2 - Script Ghost

Posicione o Ghost aonde desejar e seja feliz!

Nosso segundo tutorial de inimigo termina aqui, com a criação do segundo e ultimo inimigo do nosso jogo. Espero que tenham gostado.

Agora falta pouco para terminamos o nosso jogo, só mais um mês e terminamos!

Dúvidas, criticas e sugestões deixem ai nos comentários 🙂

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) {
 			animator.SetTrigger("atacou");
 			Instantiate(ataque, transform.position, transform.rotation);
 			atacou = true;
 		}
 		if (atacou) {
 			contagemIntervalo += Time.deltaTime;
 			if (contagemIntervalo >= intervaloAtaque) {
				atacou = false;
				contagemIntervalo = 0;
			}
		}
	}
}

ChamasAzuis.cs

using UnityEngine;
using System.Collections;

public class ChamasAzuis : MonoBehaviour {

	public float velocidade;
	public int dano;

	// Use this for initialization
	void Start () {
		Destroy (gameObject, 5f);
	}
	
	// Update is called once per frame
	void Update () {
		transform.Translate (Vector2.right * velocidade * Time.deltaTime);
	}

	void OnCollisionEnter2D(Collision2D colisor) {
		if (colisor.gameObject.tag == "Player") {
			var player = colisor.gameObject.transform.GetComponent();
			player.PerdeVida(dano);
		}
		Destroy(gameObject);
	}
}

Parte 8 – Inimigo parte 1
Indice de Unity 2D
Parte 10 – Ataque Especial

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

39 comments

  1. Victor Hugo disse:

    Cara, muito bom o tutorial! Isso é uma das coisas que eu estava querendo fazer rs, muito obrigado xD
    e novamente, muito bom tutorial!

    • Percebi quando você falou ontem. Mas podem usar o Invoke também que não tem problema algum. Agora se o personagem for atacado (Tiver um collider) recomendo chamar o cancelInvoke 😉

      Quanto a sua dúvida do outro post, tente usar a opção Is Trigger ou usar no instantiate por uma distancia um pouco maior
      Instantiate(ataque, (transform.position + vector3.right), transform.rotation);

      ou
      Instantiate(ataque, (transform.position – vector3.right), transform.rotation);

      dependendo da posição do seu personagem

  2. Karfann Nacif disse:

    Parabéns de novo meu amigo!!

    1) Gostaria de pedir indicação de algum livro ou material p/ unity.

    2) Assistir esse filme sobre Indie Games essa semana e achei muito top queria compartilhar aqui com vcs ..

    http://www.imdb.com/title/tt1942884/

    vlw!

  3. Bruno disse:

    Como sempre show de bola!! Vou deixar uma sugestão talvez alguém mais que acompanha talvez tenha essa duvida, se puder poderia ensinar a mudar o prefab do personagem quando ele adquire uma característica nova enquanto está jogando, como por exemplo o Mario quando come o cogumelo e fica maior que o normal. Abç e por favor continue o projeto

    • Opa, Bruno.

      No caso você não vai alterar exatamente o prefab. Pois isso será ima característica do Player/Inimigo já configurado no prefab.

      Isso ai na realidade seria novas animações. Ou seja quando pegasse um item, iria ativar um Trigger que mudaria para uma animação do personagem parado e grande (Teria que ter todas as outras animções dele grande também)

      Quando recebesse dano, iria ter outra ação que ativaria um Trigger dele voltando para o tamanho normal.

      Entendeu?

  4. Paulo disse:

    Ola Carlos.
    Pensei numas coisinhas para tornar o game um pouco mais rico, achas que seria possível fazeres um tutorial extra, acredito que seja complicado mas era beleza. Pensa no assunto.
    Grande abraço e boa continuação.

    1-Sistema com 3 vidas, quando o Hp do player for a zero, perde-se uma vida;

    2- Coletar moedas ou rubis e quando coletar 100 o player ganha uma vida;

    3- Um Bau/Cofre que quando o player pressionar uma tecla ele se abre e drop uma vida, um rubi com mais valor ou uma poção. Utilizando um sistema random (aleatório).

    4- Por fim, fazer o personagem empurrar caixas (podendo desenvolver pequenos enigmas) ou o fim do level ser uma porta mas para isso o player tem de pegar uma chave que colocamos algures no level.

    Ps: A ideia do Bruno também é mt da hora

    • E aê Paulo, o problema disso ai que você está pedindo é que já passou dos tutoriais deles e eu já “fechei” esse tutorial. Já estão com todos as aulas programadas para sair. =S

      1 – O Sistema de vidas entraria no tutorial de Vida que eu fiz

      2 – O sistema de Coletar Moedas também entraria no de Vida

      3 – O bau entraria num Mix de Cenário e Vida

      4 – Entra em cenário

      Por isso que eu perguntei no de Cenário o que vocês, queriam pois é um local muito grande e dá para explorar muito, mas está parte já está fechada =S

      Mas bora fazer o seguinte. Eu já estou em período de provas no mestrado, então meu tempo esta limitado (Por isso que eu já adiantei os tutoriais restantes), mas eu pretendo abrir uma enquete no final do tutorial perguntando que vocês depois desse tutorial, como outros tutoriais de outras engines, a versão para mobile, um jogo ao estilo flappybird (Fase infinita)…

      Ai vou adicionar uma nova opção, que será justamente isso ai que você está falando. Criar a segunda versão do nosso jogo com nível de aprendizagem intermediário (Esse tutorial é aqui é o básico para vocês aprenderem os conceitos de Unity e desenrolarem os seus próprios jogos):
      1 – Sistema de Pontuação
      2 – Sistema de Vida
      3 – Inventário (Guarda poção e mana)
      4 – Boss
      5 – Novos recursos do cenário (Subir corda como já me pediram)
      6 – Plataformas OneWay (Já me pediram também essa explicação)
      7 – E tudo mais que vocês pediram até antes de começar esse tutorial.

      O que acha assim? Pode ser? Mas lembrando que será uma enquete e o fato de fazer um não significa que eu não vá fazer outro. Só mudará a ordem, é lógico ^^

  5. Paulo disse:

    Ola mais uma vez :).
    Por mim tudo bem Carlos, qualquer ensinamento que faça é sempre bem vindo, afinal é o seu tempo que também está em jogo, por isso foram apenas sugestões. Mt Obrigado mais uma vês e parabéns por estes ótimos tutoriais.

  6. Paulo disse:

    Certíssimo Carlos.
    Só um aparte, na sugestão acima do Bruno, em vez de ser através das novas animações, não seria possível fazer parecido, através de um script em que se aumente a escala (scale) do personagem ? Espero ter me feito entender.
    Grande Abraço.

    • Pode ser sim Pauo, desde que não prejudique a imagem (ficar com aquela cara de imagem esticada). E no caso do Mario, são dois sprites diferente o Mario Pequeno e o Mario Grande.

      Se for alterar na escala faz assim:

      transform.scale = new Vector3(2, 2, 2);

      Onde vai receber x = 2, y = 2, z = 2. Ou:
      transform.scale.x = 2
      transform.scale.y = 2
      transform.scale.z = 2

      🙂

      • Paulo disse:

        Lool
        Até que ficou fixe, agora é preciso também melhorar o player quando ele fica grande, para tirar vantagem disso.
        Heheheehe:)

  7. Victor Hugo disse:

    fala ae Carlos! Boa noite!
    Cara, eu tenho uma nova dúvida xD
    Estou tentando fazer o inimigo andar e atacar o player com uma bola de fogo caso o player entre no range dele, se o inimigo estiver de costas eu gostaria que ele virasse para o player, tem como fazer isso? eu defini a trajetória dele(inimigo) como você fez na parte 1 do tutorial, ele fica andando pra la e pra ca… mas quando player entra no range ele ataca (que nem na parte 2) porém quando ele ta de costas pra mim ele ataca o nada … .-. ….

    Ex.: personagem olhando pra direita logo atras do inimigo olhando também para a direita, inimigo ataca pra direita…

    antes eu tinha usado aquilo que você usou para o inimigo virar para aonde o personagem esta, mas ai o inimigo começa a fazer moonwalk Oo

  8. Então Hugo. Se o seu cenário tiver buraco, há grandes chances de seu personagem cair por trocar de lado antes do tempo. O que eu recomendo é que se o personagem estiver dentro do local, ele pare de andar (A contagem do tempo também) e ele fique só atacando.

    A forma correta de fazer ele virar é justamente essa ai que você comentou e a que eu usei. Agora o Moonwalk só eu olhando o código para saber como estar o comportamento do personagem O.o

    E sim galerinha, vocês sabem que eu amo vocês, mas sinceramente estou com um trabalho foda no mestrado para o dia 10, que anda tirando minhas noites de sono por preocupação. Então vai ficar dificil eu responder muitos comentários de vocês esses dias (Não se preocupem com os tutoriais, todos já estão agendados até o dia 12/12).

    Então para tirar as dúvidas de vocês, podemos fazer de duas formas:
    1 – Vocês mandam email para mim (carlos@jogosindie.com), pois é mais fácil de controlar e ver o que eu respondi ou ainda não respondi
    2 – Eu abrir uma página aqui no Jogos Indie onde vocês mandam todas as suas dúvidas via comentários e quando eu me livrar desse terrível trabalho que está me deixando louco eu vou respondendo um por um, no próprio post (Afinal a dúvida de um, pode ser a dúvida de outros no futuro)

  9. Alvaro disse:

    Primeiramente venho parabeniza-lo pelo ótimo trabalho.
    Tenho uma duvidinha o que é esse var?
    var player =gameObj…
    pra que serve?

    • Vamos lá, uma explicação simples e direta: Serve para pegar o componente/script Player neste objeto, para podermos chamar os métodos.

      Agora vamos a explicação completa e redonda.

      var = toda vez que iniciarmos uma variável, temos que informar seu tipo, porém no C# podemos apenas informar ela como “var”, que ele tentará descobrir qual é o tipo a partir do dado de entrada. Usar var torna o código mais limpo e fácil de mexer.

      player = é o nome que demos a variável, poderia ser qualquer coisa.

      colisor.gameObject.transform.GetComponent< Player >();…

      colisor = é o objeto que colidiu com o nosso.
      gameObject = estamos acessando os dados desse objeto que colidiu
      transform = estamos “tendo acesso a aba Inspector” desse objeto (Já temos acesso ao básico como position e rotation)
      GetComponent = Estamos pegando um dos componentes extras adicionados (Aqueles do Add Component)
      Player = é o nome do componente que adicionamos, no caso o nome do script. Se quiséssemos o animator seria Animator e por ai vai.

      Ficou claro? ^^

  10. Kulyk disse:

    Tutorial muito com como sempre! parabéns pelo trabalho!

  11. arley280 disse:

    como faso um script de distancia , pq o atacke do meu inimigo e de espada , entao como seria basicamente esse script?

  12. Diego disse:

    Carlos, Se estiver ativo no site ainda, sou desenvolvedor indie tbm e estou tentando montar uma equipe.
    caso lhe interessar meu email estará disponivel para você

  13. carloswgama disse:

    Opa cara, eu até acho legal a ideia, mas por hora (Pelo menos esses próximos 2 ou 3 meses), acho dificil :/

  14. Jefferson Walfred disse:

    Carlos W. Gama, boa noite, primeiro venho te agradecer por disponibilizar esses tutoriais que são praticamente aulas, muito obrigado mesmo, minha pergunta é se tem como você me ajudar, seguir teu tutorial pra fazer o inimigo atirar, a diferença é que fiz o meu andar e atirar quando ver o personagem, mas o tiro sai do meio dele e não do olho como eu gostaria, sabe como posso resolver isso? Agradeço muito se você puder ajudar, segue o código:

    using UnityEngine;
    using System.Collections;

    public class InimigoBot1 : MonoBehaviour {

    //Faz o inimigo andar
    public float velocidade;
    public bool direcao;
    public float duracaoDirecao;

    private float tempoNaDirecao;
    private Animator animator;

    //Faz o inimigo atirar
    public float intervaloAtaque;
    private float contagemIntervalo;
    private bool atacou;
    public float distanciaAtaque;

    public GameObject ataque;
    public GameObject player;

    // Use this for initialization
    void Start () {

    animator = gameObject.transform.GetComponent();

    }

    // Update is called once per frame
    void Update () {

    // Responsável pelos passos do inimigo
    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;
    }

    //Reponsável pelos tiros
    var distancia = (player.transform.position.x – transform.position.x);
    if (distancia > 0)
    {
    transform.eulerAngles = new Vector2(0, 180);
    }
    else
    {
    transform.eulerAngles = new Vector2(0, 0);
    }

    if (!atacou && Mathf.Abs(distancia) = intervaloAtaque)
    {
    atacou = false;
    contagemIntervalo = 0;
    }
    }

    }

    //Responsável pela colisão
    void OnCollisionEnter2D(Collision2D colisor)
    {
    if (colisor.gameObject.tag == “Player”)
    {
    animator.SetTrigger(“atacou”);
    var player = colisor.gameObject.transform.GetComponent();

    player.PerdeVida(30);// dano do inimigo
    colisor.gameObject.transform.Translate(-Vector2.right);
    }
    }

    }

  15. carloswgama disse:

    Nesse script nao tem o ataque, né?

    Bom, se você tiver fazendo o ataque igual o daqui, basta fazer isso:

    var posicaoTiro = transform.position + Vector3(2, -1, 0);
    Instantiate(ataque, posicaoTiro , transform.rotation);

    o Vector(2, -1, 0), são os ajustes na posição que ele deve iniciar em relação ao inimigo que está atacando. x = 2 (Um pouco mais para frente) e y = -1 (Um pouco mais para baixo). Ai é só ir testando os melhores valores para ajustar nesse vetor.

  16. Jefferson Walfred disse:

    Muito obrigado de novo, mas conseguir resolver isso de outro jeito, pelo Sprite editor, colocando aquela bolinha do meio no olho do inimigo, assim o laser sai do olho.

  17. carloswgama disse:

    Então Jefferson, ali na realidade é a posição central do seu sprite.
    Exemplo. Se você mover essa bolinha para baixo do sprite do seu personagem, ele vai ficar acima do chão, mas o collider ainda não vai estar correto a menos que você mova.

    Movimento de rotação depende muito da posição dessa bolinha. Exemplo eu quero que um pedaço de madeira gire na ponta, então eu tenho que colocar o centro dele sendo a ponta, do contrário ele vai girar ao redor dele mesmo (Como uma hélice)

  18. Jefferson Walfred disse:

    Sim, eu entendo, mas esse inimigo que eu fiz não vira, ele é um robô que vai para um lado e para o outro atirando laser pelo olho quando o player chega perto, mas acho que vou usar tua dica agora, no player mesmo, já que o personagem que eu fiz atira e não ataca de perto como o do tutorial.

  19. Jefferson Walfred disse:

    Voltei de novo, bem vou deixar meu script de ataque logo abaixo, tentei encaixar esse vector 3 no update mas não pegou, queria colocar pro tiro sair da arma dele e também pra ele atirar para o lado que estou virado, pode dá uma mãozinha aí? c:

    using UnityEngine;
    using System.Collections;

    public class BalaPlayer : MonoBehaviour {

    public float velocidadeDaBala;
    public int dano = 1;

    // Use this for initialization
    void Start () {

    gameObject.GetComponent().Play();
    Destroy(gameObject, 1.4f);

    }

    // Update is called once per frame
    void Update () {

    transform.Translate(Vector2.right * velocidadeDaBala * Time.deltaTime);

    }

    // Colisão da bala
    void OnTriggerEnter2D(Collider2D colisor)
    {
    if (colisor.gameObject.tag == “Inimigo”)
    {
    VidaInimigo VI = colisor.gameObject.GetComponent();
    VI.Dano(dano);

    }
    }
    }

  20. Fiz tudo que você disse mas o esqueleto e o ghost não ataca o player quando ele chega perto (nem de longe). O que fazer? Ja tentei de tudo mas não vai ‘0’

  21. Olá, estou seguindo o tutorial a um tempo e tem me dado o mesmo bug diversas vezes, acredito ser por causa que minha versão do unity é 5.
    Ocorre sempre que existe um ” Destroy gameObject “. O unity diz que eu tento acessar algo que já está destruido e eu não consigo arrumar isso. Gostaria que alguém me ajudasse, por favor.

    Segue o que está escrito “bug” do unity para quem quiser saber:
    MissingReferenceException: The object of type ‘GameObject’ has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Object.Internal_InstantiateSingle (UnityEngine.Object data, Vector3 pos, Quaternion rot) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineObjectBindings.gen.cs:63)
    UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:80)
    Ghost.Update () (at Assets/Scripts/Ghost.cs:33)

    • Esse problema na realidade não depende da versão. O.o

      Se um objeto foi destruído, ele não pode mais ser acessado. Qual o script que está dando essa mensagem de tentar acessar um objeto que já foi destruído?

  22. Olá, estou de vardão por agora, (não entendo muito sobre o assunto) mas quero ajudar.
    Poderia esclarecer melhor o que acontece no seu “jogo”?
    Também gostaria que passasse o Script que você criou para cada um dos inimigos.
    O meu está funcionando, apenas ocorre um bug por causa do ” Destroy gameObject “. Por isso acredito que possa lhe ajudar, mas não sei corrigir este bug SAUHSAU

  23. Na verdade não é bem um script, quando eu vou testar o jogo do nada ele para. Ai aparece esse “erro” no console.
    Mas isso acontece com a “Plataforma Cai” e com a “ChamasAzuis”. Por causa do script que eu tenho disso.

  24. Opa, o script que esta dando esta mensagem é o script do Ghost.
    A primeira linha do void Update

    var distancia = (player.transform.position.x – transform.position.x);

    Pelo menos é essa que aparece quando clica duas vezes em cima da mensagem.

  25. Eu joguei mais um pouco para ver se não acontecia nada diferente, fiz outras coisas no jogo também.
    Deu outra mensagem também no Update do Ghost. Especificamente nesta linha:
    Instantiate (ataque, transform.position, transform.rotation);

  26. Oi Carlos muito bom seu tutorial, estou aprendendo muito com ele. Bom tenho uma dúvida aqui, na animação de ataque do Ghost o tiro saí antes da animação, como eu faço pro tiro só sair depois da animação ?

  27. Daniel Giovannini Maccheronio disse:

    Cara, eu fiz exatamente do jeito que você ensinou, a única diferença é que meu inimigo anda de um lado pro outro, só que em nenhum momento ele atira. Como posso resolver isso?

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!