Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Henrique Morato escrevi um código para Controlar a Munição. [Editado]

Bom, eu estava acompanhando as aulas e achei interessante tambem controlar a quantidade de munição do jogador. Que pode ser considerado um Status da Arma, carregada, descarregada e carregando.(Eu não fui até o final do 3 curso hehe)

Então Henrique, se tiver um tempo para dar uma olhada no código e me mandar um feedback. E para quem quiser implementar algo desse tipo.

Aqui uma imagem de como ficou: https://i.imgur.com/JOL0zGT.png

Primeiro eu editei a caixa da munição fechada, para ficar menor e com duas caixinhas. Depois criei dois scripts: IControlaMunicao e ControlaMunicao. E usei os scripts ControlaStatus, ControlaUI e ControlaInimigo.

[Editado]: Feita alterações para melhorar o controle da munição nos Scripts ControlaArma, ControlaUI e ControlaStatus.

Os códigos ficaram da seguinte forma:

IControlaMunicao

public interface IControlaMunicao
{
    void RecargaMunicao(int quantidadeDeMunicao);
}

ControlaMunicao

public class ControlaMunicao : MonoBehaviour
{
    private int tempoDeDestruicao = 5;

    void Start()
    {
        Destroy(gameObject, tempoDeDestruicao);
    }

    int MunicaoAleatoria()
    {
        int QuantidadeDeMunicao = Random.Range(5, 10);
        return QuantidadeDeMunicao;
    }

    private void OnTriggerEnter(Collider objetoDeColisao)
    {
        if (objetoDeColisao.tag == "Jogador")
        {

            objetoDeColisao.GetComponent<ControlaArma>().RecargaMunicao(MunicaoAleatoria());
            Destroy(gameObject);
        }
    }
}

ControlaArma

public class ControlaArma : MonoBehaviour, IControlaMunicao {

    public GameObject Bala;
    public GameObject CanoDaArma;
    public AudioClip SomDoTiro;
    public ControlaStatus ControlaStatus;
    private ControlaUI scripControlaUI;

        void Start ()
    {
        ControlaStatus = GetComponent<ControlaStatus>();
        scripControlaUI = GameObject.FindObjectOfType(typeof(ControlaUI)) as ControlaUI;    
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetButtonDown("Fire1") && ControlaStatus.Municao > 0 )
        {
            ControlaAudio.instancia.PlayOneShot(SomDoTiro);
            Instantiate(Bala, CanoDaArma.transform.position, CanoDaArma.transform.rotation);
            ControlaStatus.Municao --;
            scripControlaUI.AtualizarQuantidadeDeMunicao(ControlaStatus.Municao, ControlaStatus.MunicaoReserva);
        }else if(ControlaStatus.Municao == 0 && ControlaStatus.MunicaoReserva >= 1)
        {
            ControlaStatus.Municao += ControlaStatus.MunicaoReserva;
            if (ControlaStatus.Municao > ControlaStatus.MunicaoInicial)
            {
                ControlaStatus.Municao = ControlaStatus.MunicaoInicial;
            }
            ControlaStatus.MunicaoReserva -= ControlaStatus.MunicaoInicial;
            if(ControlaStatus.MunicaoReserva < 0)
            {
                ControlaStatus.MunicaoReserva = 0;
            }
            scripControlaUI.AtualizarQuantidadeDeMunicao(ControlaStatus.Municao, ControlaStatus.MunicaoReserva);
        }
    }

    public void RecargaMunicao(int quantidadeDeMunicao)
    {
        ControlaStatus.Municao += quantidadeDeMunicao;
        if (ControlaStatus.Municao > ControlaStatus.MunicaoMaxima)
        {
            ControlaStatus.Municao = ControlaStatus.MunicaoMaxima;
        }

        scripControlaUI.AtualizarQuantidadeDeMunicao(ControlaStatus.Municao);
    }
}

ControlaStatus

public class ControlaStatus : MonoBehaviour {

    public int VidaInicial = 10;
    [HideInInspector]
    public int Vida;
    public float Velocidade = 10;
    [HideInInspector]
    public int MunicaoInicial = 9;
    [HideInInspector]
    public int MunicaoMaxima = 60;
    [HideInInspector]
    public int Municao;
    [HideInInspector]
    public int MunicaoReserva;




    void Awake () {
        Vida = VidaInicial;
        Municao = MunicaoInicial;
        MunicaoReserva = MunicaoInicial;
    }



}

ControlaUI

    public void AtualizarQuantidadeDeMunicao(int municao, int municaoreserva)
    {
        ControleDaMunicaoAtual.text = string.Format(" {0}|{1} ", municao, municaoreserva);
    }
3 respostas
solução!

Oi, Matheus, tudo bom?

Fiquei muito feliz de ver você se desafiando a implementar novas coisas que não tem no curso :)

Seu código ficou muito bom, vou dar só algumas pequenas dicas pra você refatorar e ficar ainda melhor.

Magic numbers e literal strings

Uma coisa que você pode fazer (e falo um pouco sobre isso no curso 3) é evitar strings literais e números mágicos.

Na hora de definir variáveis não tem como evitar mas quando for usar uma tag como :

if (objetoDeColisao.tag == "Jogador")

Eu iria por um caminho como criar um script tipo:

public class Tags 
{
    public const string Jogador = "Jogador";
}

E nele definir todas as tags que você tá usando no Unity, porque pensa que depois você pensa 'poxa, a tag jogador não faz mais sentido ter esse nome gostaria de mudar' você vai ter que ir em vários scripts, dessa forma aqui seria um lugar só e evita erros bestas de digitação. Aí seu código de teste ficaria algo como:

if (objetoDeColisao.tag == Tags.Jogador)

const é um modificador que deixa sua variável constante então você pode chamar ela diretamente pela classe e não precisando passar pela instância já que seu valor não muda.

Outros pormenores

O seu script ControlaMunicao não é bem um controle de munição, ele cuida de cada instância de munição que você vai pegar, a gente tava usando o nome Controle para algo mais geral que mexe com tudo, como o ControlaJogador que faz tudo do Jogador. Então como no jogo ele vai aparecer várias vezes eu iria por algo só como Municao

O update do ControlaArma tem muito código, daria para refatorar e quebrar muita coisa em métodos.

Essa limitação de munição mínima e máxima você pode usar o método Mathf.Clamp ao invés de fazer vários ifs

E outra coisa que você pode fazer também (se quiser, claro) é limitar a quantidade de tiros por segundo e trocar ao invés de click pra atirar deixar o usuário segurar o botão do mouse. Mas isso é mais uma coisa de preferência também.

Henrique, obrigado pelo retorno construtivo.

Vou me atentar ao uso de constantes, eu tinha uma classe Tags criada, mas não lembrei de usar kkkkkkkkk

Mathf.Clamp, vou procurar ver como funcionar e colocar no código, eu lembro que em uma das aulas tinha algo sobre.

Essa ideia de tiros por segundo é muito boa, outra ideia seria manter os dois modos clicando e mantendo pressionado, podendo trocar entre os modos usando algum input, eu havia pensado em colocar algum input para fazer a recarga, ao invés de trabalhar com a recarga travada em 9.

obs.: No meu código ControlaArma tinha um método que não estava sendo usado em lugar nenhum kkkkkkk, mas já corrigi.

Esse:

    void MunicaoAtual(int municao)
    {
        ControlaStatus.Municao -= municao;
        municao--;
    }

Fiquei contente com a resposta, e estou bem animado com a Unity.

Muito bom, agora é continuar os estudos e melhorando o seu jogo.

Se quiser também você pode trocar os modelos 3D por outros da Asset Store e publicar o seu jogo :)