Menu

05 – Tutorial Intermediário – Personagem 2 – Habilidade

E aqui estamos para mais um tutorial! Desta vez vamos criar as habilidades da nossa querida ninja!


As habilidades serão:

1 – Ataque Triplo (Lançar 3 lanças em diferentes direções)
2 – Double Jump/Pulo Duplo (Um segundo pulo)
3 – Cura.

Já está meio facinho depois que fizemos o do primeiro ninja, não é mesmo? Aqui a ideia será a mesma do tutorial retrasado!

Habilidade 1

A primeira habilidade, Ataque Triplo é beeeem parecido com o Slash, porém ao invés de criar 1 único ataque, iremos criar 3, um subindo outro reto e o terceiro descendo.

Então bora lá repetir aqueles nossos velhos processos para refrescar a mente de vocês. O primeiro é criar um script (C#) com o nome AtaqueTriplo dentro da pasta scripts/jogador/habilidade:

01- Tutorial Personagem 2 - Habilidade

Podemos então abrir o nosso script e dizer que ele implementa a interface IHabilidade (Aproveitamos, para implementar logo aqueles métodos, +o custo da habilidade será 2MP):

02- Tutorial Personagem 2 - Habilidade

Script: AtaqueTriplo.cs

using UnityEngine;
using System.Collections;
using System;

public class AtaqueTriplo : IHabilidade {

    private Personagem2 personagem;

    public void executar() {
    }

    public int getCustoHabilidade() {
        return 2;
    }

    public bool podeUsar() {
        return (personagem.getStatus().getMP() >= getCustoHabilidade());
    }

    public void setPersonagem(GameObject personagem) {
        this.personagem = personagem.GetComponent();
    }
}

Já vimos anteriormente cada um desses métodos, do porque que fizemos assim, mas ai vai uma revisão:

1 – Criamos uma variável privada do tipo Personagem2 , para acessar os dados da nossa ninja;
2 – Em getCustoHabilidade, informamos quanto pontos de magia, essa habilidade vai custar;
3 – podeUsar, verifica se o personagem tem mp e nível suficiente para usar, por enquanto estamos só colocando se tem MP, para podermos testar;
4 – em setPersonagem pegamos o personagem que usou essa habilidade e buscamos o script Personagem2, afinal essa habilidade é exclusiva do Personagem2. Se quiséssemos fazer algo genérico, para qualquer personagem, teríamos que usar IPersonagem e ter pelo menos mais um método ai na nossa interface para buscar o gameObject do script para podermos acessa a sua posição.

Bom, essas etapas que vimos são comuns para qualquer habilidade, então vamos trabalhar no que é exclusivo desta habilidade.

No método executar, vamos primeiro verificar se o personagem pode usar a habilidade através do método podeUsar:

Script: AtaqueTriplo.cs

    public void executar() {
        if (podeUsar()) {

        }
    }

Lembra-se da nossa habilidade Slash? Aqui vai ser a mesma coisa, só que o nosso prefab será a nossa kunai. As três kunais que vamos gerar, elas iniciam do mesmo ponto ao mesmo tempo, porém uma está com o eixo Z em 20° (Inclinado para cima), outra em 0° (Inclinação normal) e a ultima em -20° (Inclinação para baixo):

03- Tutorial Personagem 2 - Habilidade

Temos três formas diferentes de fazer isso:

1 – Escrever o mesmo código 3 vezes (Péssimo)
2 – Escrever um loop que repete 3 vezes (Bom e centralizado)
3 – (Escrever um método só para criar o objeto) (Simples, sem dor de cabeça)

Eu acho que a segunda opção é a que eu usaria para deixar tudo já centrado no método executar, porém a segunda forma usa um pouco mais de lógica, o que pode complicar um pouco para vocês, então vou usar a terceira alternativa, que consiste em criar um método só para isso.

Neste caso, é a primeira coisa que eu vou fazer, é criar um método chamado criaKunai, que recebe como parâmetro o grau que iremos informar em Z:

Script: AtaqueTriplo.cs

    private void criaKunai(float grau) {

    }

Dentro desse método será basicamente igual ao nosso método de ataque, só que iremos definir o grau de inclinação da kunai, então vamos lá fazer aquele mesmo código:

Script: AtaqueTriplo.cs

    private void criaKunai(float grau) {
        var prefabKunai = Resources.Load("prefabs/jogador/Kunai") as GameObject;
        var objAtaque = GameObject.Instantiate(prefabKunai).GetComponent();      //Cria o objeto no cenário (Hierarchy)
        objAtaque.destroiObjeto(5f);                        //Destroi objeto em 5 Segundos

        objAtaque.direita = personagem.getDireita();        //Define a direção que o objeto vai andar
        if (personagem.getDireita())                        //Verifica de qual lado do personagem será criado
            objAtaque.transform.position = personagem.transform.position + Vector3.right;
        else
            objAtaque.transform.position = personagem.transform.position - Vector3.right;

        objAtaque.dano = personagem.getStatus().getAtaque(); //Define o dano que a Kunai causa
    }

Aqui é basicamente aquele mesmo script adaptado do ataque da Ninja, então sem problema correto? Onde lá nós podíamos chamar direto transform ou this.transform pois era um atributo da própria classe, aqui temos que dizer a quem o transform pertence, já que ele não é da classe atual (AtaqueTriplo). E o direita por ser um atributo protected (Classes que não sejam filhas, não tem acesso), então usamos o método getDireita(), para recuperar esse valor. E no inicio buscamos o prefab informado através do método Resources.Load.

Sem novidades até essa parte, então vamos para o que é novo. Vocês se lembram de que usávamos o método Translate para o personagem sair da posição atual e andar mais um tanto, correto? Aqui é parecido, usaremos o método Rotate para ele rotacionar da rotação atual para o tanto que acrescentarmos (o grau no parâmetro):

Script: AtaqueTriplo.cs

    private void criaKunai(float grau) {
        var prefabKunai = Resources.Load("prefabs/jogador/Kunai") as GameObject;
        var objAtaque = GameObject.Instantiate(prefabKunai).GetComponent();      //Cria o objeto no cenário (Hierarchy)
        objAtaque.destroiObjeto(5f);                        //Destroi objeto em 5 Segundos

        objAtaque.direita = personagem.getDireita();        //Define a direção que o objeto vai andar
        if (personagem.getDireita())                        //Verifica de qual lado do personagem será criado
            objAtaque.transform.position = personagem.transform.position + Vector3.right;
        else
            objAtaque.transform.position = personagem.transform.position - Vector3.right;

        objAtaque.dano = personagem.getStatus().getAtaque(); //Define o dano que a Kunai causa

        //Inclinação
        objAtaque.transform.Rotate(0f, 0f, grau);
    }

Com isso:

objAtaque.transform.Rotate(0f, 0f, grau);

Queremos dizer que nossa kunai (objAtaque) vai sair da rotação atual (X = 0, Y = 0, Z = 0) para o que acrescentarmos. Não acrescentamos nada em X e Y (0f), porém acrescentamos o grau em Z lá no ultimo parâmetro do Rotate.

Bom, agora no método executar vai ficar bem simples, basta: apenas chamar a animação; chamar o método criaKunai 3 vezes com os devidos graus; diminuir o MP do personagem; e informar que a ninja está atacando:

Script: AtaqueTriplo.cs

    public void executar() {
        if (podeUsar()) {
            personagem.animator.SetTrigger("atacou"); //Ativa animação

            //Cria as Kunais
            criaKunai(20f); //Rotação (X = 0, Y = 0, Z = 20)
            criaKunai(0f); //Rotação (X = 0, Y = 0, Z = 0)
            criaKunai(-20f); //Rotação (X = 0, Y = 0, Z = -20)

            personagem.atacando = true;               //Informa para o script que está atacando
            personagem.getStatus().usaMagia(getCustoHabilidade()); //Diminui o custo da magia no MP
        }
    }

Com isto, nossa habilidade já está pronta, basta apenas no script Personagem2, informar no método ataque que se for apertado o botão Habilidade1, chama essa habilidade. Também precisamos criar uma variável para nossa habilidade e no método Awake passar para o script da habilidade que é o gameObject da Ninja:

using UnityEngine;
using System.Collections;
using System;

public class Personagem2 : Jogador { 

    public AtaqueAndante kunai;
    public IHabilidade habilidade1 = new AtaqueTriplo();

    void Awake() {
        status = new Status(10, 12, 5); //HP 10 | MP 12 | Ataque 5
        habilidade1.setPersonagem(this.gameObject);
    }
...

Assim que a habilidade for definida no nosso script Personagem2, basta agora no método ataque verificar se o botão foi apertado. Caso sim, a gente pede para executar a habilidade:

Script: Personagem2.cs

    protected override void atacar() {
        if (!atacando) {

            //Ataque comum
            if (Input.GetButtonDown("Ataque")) {    //Apertou o botão de ataque
                animator.SetTrigger("atacou");      //Ativa animação
                var objAtaque = Instantiate(kunai); //Cria o objeto no cenário (Hierarchy)
                objAtaque.destroiObjeto(5f);        //Destroi objeto em 5 Segundos

                objAtaque.direita = direita;        //Define a direção que o objeto vai andar
                if (direita)                        //Verifica de qual lado do personagem será criado
                    objAtaque.transform.position = transform.position + Vector3.right;
                else
                    objAtaque.transform.position = transform.position - Vector3.right;

                objAtaque.dano = status.getAtaque(); //Define o dano que a Kunai causa

                atacando = true;                    //Informa que o personagem está atacando
            }

            //Habilidades
            if (Input.GetButtonDown("Habilidade1")) //Habilidade AtaqueTriplo
                habilidade1.executar();
        } else 
            atacando = animator.GetCurrentAnimatorStateInfo(0).IsName("atacando");
    }

Agora você já pode testar e verificar que existe uma falha no script.

Ao pedir para atacar, nosso personagem do lado direito executar o ataque normal:

04- Tutorial Personagem 2 - Habilidade

Porém do lado esquerdo, não…

05- Tutorial Personagem 2 - Habilidade

Você sabe me dizer por que? E ai? Pensou um pouquinho? Já tem seu palpite? Então bora lá, o motivo está no nosso script AtaqueAndante dentro da condição direita = false:

Script: AtaqueAndante.cs

	void Update () {
        if (!direita)
            transform.eulerAngles = new Vector2(0, 180); //Invertemos o eixo Y

        transform.Translate(Vector3.right * velocidade * Time.deltaTime);

	}

Aqui nos trocamos o ângulo do nosso ataque obrigatoriamente para X = 0, Y = 180 e Z = 0. Neste caso, podemos usar uma linha a mais para buscar o valor apenas de Z e depois informar os 3 valores de forma correta (Sem inverter o eixo de Z):

Script: AtaqueAndante.cs

        if (!direita) {
            var z = transform.eulerAngles.z;
            transform.eulerAngles = new Vector3(0, 180, z); //Invertemos o eixo Y
        }

“Carlos, posso pegar o valor de transform.rotation.z?” Não, a resposta é não, pois o rotation não armazena os valores em graus. Se você quiser pegar e alterar os valores em graus, tem que usar o eulerAngles, mesmo. O rotation ele é um pouco mais complicado, armazena os dados em relação ao mundo em uma escala de -1.0 a 1.0, mas para tentar ajudar a entender um pouco a ideia seria como se esquerda (180°) fosse 1 e direita (0/360°) fosse zero, porém não tão simples assim.

Feito esta alteração, o ataque já vai funcionar normal para os dois lados!

Habilidade 2

Nossa segunda habilidade também será bem fácil e iremos aprender algumas coisinhas novas de programação que podem te ajudar em seus jogos!

Nossa próxima habilidade será o Pulo Duplo, então já sabemos que ela não vai acontecer dentro do método ataque e sim do mover, não é mesmo (Afinal os códigos em ataque não podem ser executados se o personagem não estiver no chão e essa habilidade só vai funcionar se o personagem não estiver no chão)? Mas antes de se preocupar com isso, vamos criar nossa habilidade!

Crie um script (C#) chamado PuloDuplo dentro da pasta scripts/jogador/habilidades:

06- Tutorial Personagem 2 - Habilidade

Abrindo o projeto vamos executar o mesmo trabalho de sempre: Informar que o script vai implementar IHabilidade; Implementar os métodos obrigatórios; criar uma variável personagem do tipo Personagem2; Informar que o custo da habilidade é 3MP:

Script: PuloDuplo.cs

using UnityEngine;
using System.Collections;
using System;

public class PuloDuplo : IHabilidade {

    private Personagem2 personagem;

    public void executar() {
        
    }

    public int getCustoHabilidade() {
        return 3;
    }

    public bool podeUsar() {
        return (personagem.getStatus().getMP() >= getCustoHabilidade());
    }

    public void setPersonagem(GameObject personagem) {
        this.personagem = personagem.GetComponent();
    }
}

Bom, agora precisamos verificar se o personagem está realmente no chão. Neste caso lá no nosso script Jogador, precisamos criar um método para retornar a variável estaNoChao:

Script: Jogador.cs

    public bool getEstaNoChao() {
        return estaNoChao;
    }

Bom, após fazer esse método lá no script Jogador, já podemos verificar no nosso script PuloDuplo se o personagem está ou não no chão. Essa habilidade só vai poder ser usada se o personagem não estiver no chão, então no nosso método podeUsar, vamos adicionar mais uma condição:

Script: PuloDuplo.cs

    public bool podeUsar() {
        return (personagem.getStatus().getMP() >= getCustoHabilidade() && !personagem.getEstaNoChao());
    }

Ou seja, se o personagem tiver MP maior ou igual ao custo da habilidade E NÃO (!) estiver no chão, então a habilidade poderá ser usada.

Tudo bem fácil e tranquilo até ai, certo? Então vamos implementar nosso método executar. A primeira coisa como sempre é fazer a verificar se a habilidade pode ser executada:

Script: PuloDuplo.cs

    public void executar() {
        if (podeUsar()) {

        }
    }

Caso ela possa, aqui será bem simples. Iremos aplicar novamente a força do pulo ao personagem para cima e chamaremos o trigger do animator voou (Fora reduzir o custo da habilidade é lógico):

Script: PuloDuplo.cs

    public void executar() {
        if (podeUsar()) {
            personagem.GetComponent().AddForce(Vector3.up * personagem.forcaPulo); //Aplica o pulo
            personagem.animator.SetTrigger("voou");                 //Ativa animação
            personagem.getStatus().usaMagia(getCustoHabilidade());  //Reduz o custo da magia
        }
    }

Mais fácil, impossível, né? Recuperamos o componente Rigidbody2D do nosso objeto Personagem2 e aplicamos uma força para cima (Vector3.up) com a força que definimos na variável forcaPulo.

“Carlos por que no script Jogador usamos transform.up ao invés de Vector3.up?”. Bom… por nada, não há diferença na realidade, o transform é uma variável do tipo Vector3, então ela também tem essa variável estática “up” que é do tipo Vector3, que retorna: X = 0, Y = 1 e Z = 0. Então tanto faz usar uma ou outra. Aqui usamos o Vector3.up, para não ter que escrever “personagem.transform.up”.

Depois de aplicar a força, dizemos para o animator que o trigger voou foi apertado para que ele faça a troca de animação e por fim reduzimos o custo da magia.

Agora iremos trabalhar na classe Personagem2, então já sabem: Criaremos a variável habilidade2 do tipo IHabilidade, que instancia o tipo PuloDuplo(new PuloDuplo), depois no método Awake, passamos o gameObject atual como parâmetro:

Script: Personagem2.cs

using UnityEngine;
using System.Collections;
using System;

public class Personagem2 : Jogador { 

    public AtaqueAndante kunai;
    public IHabilidade habilidade1 = new AtaqueTriplo();
    public IHabilidade habilidade2 = new PuloDuplo();

    void Awake() {
        status = new Status(10, 12, 5); //HP 10 | MP 12 | Ataque 5
        habilidade1.setPersonagem(this.gameObject);
        habilidade2.setPersonagem(this.gameObject);
    }
...

Terminado essa parte bem fácil, bora para o que tem de novo, afinal ensinar uma habilidade que não tem nada de novo não faria sentido em um tutorial.

Como falei mais cedo, essa habilidade não é um ataque e sim um movimento, logo ela vai estar dentro do método mover, porém o método mover ele é implementado em Jogador e não em Personagem2. E agora josé?

Bom, não sei se vocês se lembram, mas nós sobrescrevemos (override) o método ataque (que era apenas abstrato, ou seja, tinha que ser refeito em uma classe filha). Aqui faremos basicamente a mesma coisa. Porém para eu sobrescrever um método em C#, este método tem que ser do tipo abstrato/abstract (Não implementado ainda) ou virtual (Implementado, mas que pode ser refeito por uma classe filha). Sendo assim, iremos voltar ao script Jogador e alterar a declaração do método de “void mover()” para “protected virtual void mover()”:

Script: Jogador.cs

    protected virtual void mover() {
...

Com isso já estamos dizemos que as classes filhas (protected = pode ser usado por classe filha) podem alterar (virtual = permite alteração) o método mover. Agora podemos voltar ao nosso script Personagem2 (Cuidado ai com essa tanta troca de script, para não escrever no script errado) e adicionar o método mover:

Script: Personagem2.cs

    protected override void mover() {
        
    }

Só de fazer isso, o seu personagem vai perder todos os comandos que ele já possuía dentro do método mover em Jogador (Logo não vai mais andar e nem pular, já que esse método agora está vazio). Com isso podemos entender que todo método que for reescrito por uma classe filha, vai ficar valendo o conteúdo do código que tiver na classe mais abaixo na herança (Ou seja, nos filhos).

Dê play e verá que seu personagem não mais vai andar, por ter perdido tudo que foi implementado no método mover da classe Jogador. Se nós não quisermos ter que reescrever tudo de novo (Não, nós não queremos ter que reescrever tudo de novo!), então podemos chamar o método mover da classe mãe, usando a variável base:

Script: Personagem2.cs

    protected override void mover() {
        base.mover();
    }

Agora sim, caso dê play, todo comando que havia sido implementado no método mover da classe Jogador também vai valer no método mover da classe Personagem2.

“Huuuum, interessante, mas para que eu quero fazer isso?”

Calma, calma. Agora que nós já devolvemos toda implementação feita no método mover da classe Jogador, podemos após isso adicionar apenas o que queremos de novo no nosso script, que seria verificar se o botão Habilidade2 foi apertado e caso sim, chamaremos a habilidade:

Script: Personagem2.cs

    protected override void mover() {
        base.mover();

        if (Input.GetButtonDown("Habilidade2"))
            habilidade2.executar();
    }

Em outras palavras, isso ai que fizemos é exatamente igual a isso aqui:

    protected virtual void mover() {
        //Andar
        if (Input.GetAxisRaw("Horizontal") > 0) {
            if (!direita)
                inverter();

            transform.Translate(Vector3.right * velocidade * Time.deltaTime);

            direita = true;
        }

        if (Input.GetAxisRaw("Horizontal") < 0) {
            if (direita)
                inverter();
            transform.Translate(-Vector3.right * velocidade * Time.deltaTime);
            direita = false;
        }

        animator.SetFloat("velocidade", Mathf.Abs(Input.GetAxisRaw("Horizontal")));

        //Pular
        estaNoChao = Physics2D.Linecast(transform.position, chaoVerificador.transform.position, 1 << LayerMask.NameToLayer("Piso"));
        if (Input.GetButtonDown("Jump") && estaNoChao) {
            GetComponent().AddForce(transform.up * forcaPulo);
        }

        animator.SetBool("estaNoChao", estaNoChao);

        if (Input.GetButtonDown("Habilidade2"))
            habilidade2.executar();


    }

E ai? O que é melhor? Ter que escrever tudo de novo para adicionar no final 2 linhas, ou apenas chamar o base.mover()? Entendeu agora a vantagem de fazer da forma que fizemos? Bom, com isso terminamos nossa habilidade! Basta agora dar o play, verificar se ficou bom e se achar necessário fazer ajustes lá na velocidade de transição das animações:

07- Tutorial Personagem 2 - Habilidade

(Removi o Has Exit Time e tirei a duração da transição)

08- Tutorial Personagem 2 - Habilidade

Habilidade 3

A nossa terceira e ultima habilidade é a Cura. Nós praticamente já vimos lá nas habilidades do Personagem1, como fazer a cura não é mesmo? Então porque eu vou ensinar algo tão básico? Bom, porque eu vou mostrar outro componente do Unity!

Na nossa aba Hierarchy clique com o botão direito em um canto vazio (Ou lá no menu GameObject mesmo) e procure por Particle System:

09- Tutorial Personagem 2 - Habilidade

Vai começar a surgir umas bolinhas infinitas no seu personagem:

10- Tutorial Personagem 2 - Habilidade

A ideia aqui é que essas bolinhas apareçam quando nosso personagem se cure. Então bora fazer uns ajustes lá na aba Inspector desse Particle System.

1 – Remover o Loop (Repetição) infinito:

11- Tutorial Personagem 2 - Habilidade

Desta forma após completar o tempo de duração, nossas particular não vamos mais continuar sendo criadas. Se quisermos testar, temos que apertar o botão Simulate:

12- Tutorial Personagem 2 - Habilidade

2 – Próximo ponto, é que 5 segundos é muita coisa, então vamos mudar para 1 segundo de duração:

13- Tutorial Personagem 2 - Habilidade

3 – Vamos mudar para a cor das partículas para verde (O que normalmente é usado em cura):

14- Tutorial Personagem 2 - Habilidade

4 – Caso reparem, nossas particular vão para cima em forma de cone, vamos trocar para uma forma circular:
Clica em Shape.

15- Tutorial Personagem 2 - Habilidade

Troca a forma de Cone para Sphere:

16- Tutorial Personagem 2 - Habilidade

17- Tutorial Personagem 2 - Habilidade

5 – A duração de produção está boa, mas as partículas ficam por muito tempo no cenário, então vamos reduzir o tempo de vida das partículas de 5 segundos para 1 segundo:

18- Tutorial Personagem 2 - Habilidade

19- Tutorial Personagem 2 - Habilidade

Com isso, acho que nossas partículas já estão prontas, então basta apenas trocar esse nome para algo que você saiba do que se trata como CuraParticulas ou ParticulasDeCura:

20- Tutorial Personagem 2 - Habilidade

E depois transformar esse objeto em um prefab dentro de Resources/prefabs/jogador:

21- Tutorial Personagem 2 - Habilidade

Já podemos excluir esse objeto da aba Hierarchy e criar um novo script chamado Cura dentro de scripts/jogador/habilidades:

22- Tutorial Personagem 2 - Habilidade

Aqui o procedimento é o mesmo. Vamos implementar IHabilidade, criar uma variável do tipo Personagem2, implementar os métodos, informar o custo da habilidade (6 MP) e no método executar verificar se pode usar a habilidade:

Script: Cura.cs

using UnityEngine;
using System.Collections;
using System;

public class Cura : IHabilidade {

    private Personagem2 personagem;

    public void executar() {
        if (podeUsar()) {

        }
    }

    public int getCustoHabilidade() {
        return 6;
    }

    public bool podeUsar() {
        return (personagem.getStatus().getMP() >= getCustoHabilidade());
    }

    public void setPersonagem(GameObject personagem) {
        this.personagem = personagem.GetComponent();
    }
}

Bom, após fazer esse processo repetitivo de sempre, vamos ao que há de novo! Dentro do método executar, vamos buscar o status do personagem e usar o método recuperaHP, para curar nosso personagem em 5HP. Lembrando-se de logo em seguida remover o custo da magia:

Script: Cura.cs

    public void executar() {
        if (podeUsar()) {
            personagem.getStatus().recuperaHP(5); //Recupera 5HP
            personagem.getStatus().usaMagia(getCustoHabilidade());
        }
    }

Se nós não fossemos usar as partículas, nosso script acabava aqui, mas como iremos, então vamos buscar o prefab e adiciona o prefab na posição do personagem:
Script: Cura.cs

    public void executar() {
        if (podeUsar()) {
            var prefabParticulas = Resources.Load("prefabs/jogador/CuraParticulas"); //O mesmo nome e pasta onde está o prefab
            var particulas = GameObject.Instantiate(prefabParticulas) as GameObject; //Cria o objeto na scene
            particulas.transform.position = personagem.transform.position; //Faz as particulas surgirem onde o personagem está
            particulas.transform.parent = personagem.transform; //Faz as particulas seguirem o personagem, quando ele anda
            GameObject.Destroy(particulas, 2f);                 //Destroi as particulas em 2 segundos

            personagem.getStatus().recuperaHP(5); //Recupera 5HP
            personagem.getStatus().usaMagia(getCustoHabilidade());
        }
    }

Agora vamos as explicações.

1 – var prefabParticulas = Resources.Load(“prefabs/jogador/CuraParticulas”);
Aqui buscamos o prefab que iremos criar na Scene de acordo com a sua posição na aba Project dentro da pasta Resources.
2 – var particulas = GameObject.Instantiate(prefabParticulas) as GameObject;
Criamos o objeto na Scene (Aba Hierarchy) e buscamos suas informações (GameObject).
3 – particulas.transform.position = personagem.transform.position;
Dizemos que a posição das partículas será a mesma do personagem lá na scene.
4 – particulas.transform.parent = personagem.transform;
Dizemos que as partículas vão ser filhas do objeto do personagem:

24- Tutorial Personagem 2 - Habilidade

O que significa que se o personagem se mover, as partículas também irão (Caso não queira isso, é só remover).

5 – GameObject.Destroy(particulas, 2f);
O objeto na aba Hierarchy irá ser destruído em 2 segundos após sua criação (Afinal não terá mais utilidade mesmo).
As outras duas linhas, vocês já conhece.

Então vamos fazer as alterações necessárias no script Personagem2 agora para testar e finalizar nosso tutorial!

De volta ao script Personagem2, é o mesmo processo de sempre, criar a variável habildiade3 e instanciar o objeto Cura, em seguida definir no método Awake quem é o gameObject:

Script: Personagem2.cs

using UnityEngine;
using System.Collections;
using System;

public class Personagem2 : Jogador { 

    public AtaqueAndante kunai;
    public IHabilidade habilidade1 = new AtaqueTriplo();
    public IHabilidade habilidade2 = new PuloDuplo();
    public IHabilidade habilidade3 = new Cura();

    void Awake() {
        status = new Status(10, 12, 5); //HP 10 | MP 12 | Ataque 5
        habilidade1.setPersonagem(this.gameObject);
        habilidade2.setPersonagem(this.gameObject);
        habilidade3.setPersonagem(this.gameObject);
    }
...

Próximo passo é no método de ataque mesmo, fazer a verificação se o personagem apertou ou não o botão da Habilidade3, caso sim, chamamos a habilidade:

Script: Personagem2.cs

    protected override void atacar() {
        if (!atacando) {

            //Ataque comum
            if (Input.GetButtonDown("Ataque")) {    //Apertou o botão de ataque
                animator.SetTrigger("atacou");      //Ativa animação
                var objAtaque = Instantiate(kunai); //Cria o objeto no cenário (Hierarchy)
                objAtaque.destroiObjeto(5f);        //Destroi objeto em 5 Segundos

                objAtaque.direita = direita;        //Define a direção que o objeto vai andar
                if (direita)                        //Verifica de qual lado do personagem será criado
                    objAtaque.transform.position = transform.position + Vector3.right;
                else
                    objAtaque.transform.position = transform.position - Vector3.right;

                objAtaque.dano = status.getAtaque(); //Define o dano que a Kunai causa

                atacando = true;                    //Informa que o personagem está atacando
            }

            //Habilidades
            if (Input.GetButtonDown("Habilidade1")) //Habilidade AtaqueTriplo
                habilidade1.executar();

            if (Input.GetButtonDown("Habilidade3")) //Habilidade Cura
                habilidade3.executar();
        } else 
            atacando = animator.GetCurrentAnimatorStateInfo(0).IsName("atacando");
    }

E com isso, finalizamos a terceira habilidade do Personagem2. Podem salvar o script e testar se está tudo ok!
Caso sim, já podemos transformar o Personagem2 em um prefab junto do Personagem1:

25- Tutorial Personagem 2 - Habilidade

Espero que tenham gostado desse tutorial ^^. Quarta que vem eu apresento para vocês uma ferramenta web para criação de PixelArt para quem quiser suas próprias arts. E seguiremos com a criação do Menu inicial do nosso jogo aprendendo um pouco de canvas e um menu de configuração.

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

2 comments

  1. Natan disse:

    Parabéns pelos tutoriais,ainda estou no básico mas são todos muito completos.Muito boa iniciativa a sua de ajudar quem quer desenvolver jogos,e o melhor é que você nem cobra por isso.Estou começando agora e desde já fico muito agradecido por todo esse conteúdo e por seus ensinamentos.

    • Valeu cara ^^

      Quanto a esse lance de cobrar eu não curto não. Sei que dá um senhor trabalho fazer o tutorial e ficar dando suporte nos comentários, mas parece que estou privando alguém de obter conhecimento que ela tanto quer por ela não ter dinheiro ou querer gastar com isso. Mas não sou contra não quem cobra, por outro lado acho que quando você paga por algo, você valoriza mais do que quando tem isso de graça (Eu ao menos sou assim). Maaaas, não faz meu estilo cobrar, prefiro ver vocês conseguindo construir seus próprios jogos sozinhos.

      Talvez num futuro próximo eu “cobre” pelo meu conhecimento. Não aqui ou dessa forma diretamente, mas sim por trabalhar em uma faculdade/universidade ou algo no estilo, onde o local cobre dos alunos, afinal o mundo é capitalista e o dinheiro tem que vir de algum lugar. Mas mesmo que isso aconteça e sobre algum tempo para eu continuar com os tutoriais aqui, eles sempre serão de graça. ^^

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!