3
respostas

Rotação do Chefe

Olá, professor. Infelizmente estou enfretando o mesmo problema dos outros alunos referente ao zombie chefe bater no jogador sem rotacionar. Eu tentei implementar as dicas dos outros alunos, e o que acontece é que se o personagem estiver nas diagonais da frente do chefe, ele vai rotacionar, mas se estiver nas costas do chefe, por exemplo, já não rotaciona. Eu tentei o método:

transform.rotation = Quaternion.LookRotation(navMeshAgent.velocity.normalized);

Dentro e fora do condiconal "estouPertoDojogador". Se estiver fora do condicional, o zumbi simplesmente vira de costas quando não deveria kkk. O personagem estando na sua frente, ele bate e automaticamente dá as costas pro personagem (e continua batendo). Se estiver dentro do condicional, na parte do else, nada acontece, ele não rotaciona e nem dá as costas pro jogador.

também tentei o método:

    public void Rotacionar(Vector3 direcao)
    {
        var speed = 20;
        Vector3 novaDirecao = Vector3.RotateTowards(transform.forward, direcao, speed * Time.deltaTime, 0.0f);
        Quaternion novaRotacao = Quaternion.LookRotation(novaDirecao);
        meuRigidbody.MoveRotation(novaRotacao);
    }

E é justamente com esse que ele rotaciona somente nas diagonais, mas ignora a rotação para as costas. Atualmente meu script está assim:

public class controlaChefe : MonoBehaviour
{

    private Transform jogador;
    // Variável que guardará o transform do jogador.

    private NavMeshAgent agente;
    // Variável que guardará o componente NavMeshAgent.

    private controlaStatus statusChefe;

    private animacaoAtores animaChefe;

    private controlaMovimentoAtores rotacaoChefe;

    private int danoMin;

    private int danoMax;

    private Rigidbody meuRigidbody;

    // Start is called before the first frame update
    void Start()
    {

        jogador = GameObject.FindWithTag("Player").transform;
        // Atribui à viariável jogador o transform de um game object com a tag de player.

        agente = GetComponent<NavMeshAgent>();
        // Atribui à variável jogador o componente NavMeshAgent.

        statusChefe = GetComponent<controlaStatus>();

        animaChefe = GetComponent<animacaoAtores>();

        rotacaoChefe = GetComponent<controlaMovimentoAtores>();

        meuRigidbody = GetComponent<Rigidbody>();

        agente.speed = statusChefe.speed;

        danoMin = 30;

        danoMax = 40;
       
    }

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

        perseguir();

        atacar();

    }

    private void perseguir()
    {

        agente.SetDestination(jogador.position);

        animaChefe.AnimarMovimento(agente.velocity.magnitude);

    }

    private void atacar()
    {

        bool estouPertoDoJogador = agente.remainingDistance <= agente.stoppingDistance;

        if (agente.hasPath == true)
        {
            Vector3 direcao = jogador.position - transform.position;

            Rotacionar(direcao);

            if (estouPertoDoJogador)
            {

                animaChefe.Atacar(true);

            }
            else
            {
               
                animaChefe.Atacar(false);

            }
        }

    }

    private void AtacaJogador()
    {

        int dano = Random.Range(danoMin, danoMax);

        //jogador.GetComponent<controlaJogador>().TomarDano(dano);

    }

    public void Rotacionar(Vector3 direcao)
    {
        var speed = 20;
        Vector3 novaDirecao = Vector3.RotateTowards(transform.forward, direcao, speed * Time.deltaTime, 0.0f);
        Quaternion novaRotacao = Quaternion.LookRotation(novaDirecao);
        meuRigidbody.MoveRotation(novaRotacao);
    }
}

Desde já, agradeço.

3 respostas

Tenta trocar o Rotacionar pra:

public void Rotacionar(Vector3 direcao)
    {
        Quaternion novaRotacao = Quaternion.LookRotation(direcao);
        meuRigidbody.MoveRotation(novaRotacao);
    }

Seria talvez ligar desligar a rotação do chefe agente.updateRotation = false e ligar de novo e rodar essas duas coisas (Rotacionar e updateRotation) somente quando tiver perto do jogador e fora isso deixar a navmesh agir.

Essa função do rotacionar até funcionou, mas somente depois de eu desligar o NavMesh. Eu imaginei que como o problema estava ocorrendo por causa do NavMesh, seria melhor desligá-lo quando o chefe estivesse perto do jogador, para que a animação de ataque aconteça sem demais problemas,e assim que o personagem pegasse distancia do jogador, o NavMesh seria ligado novamente. Meu código ficou assim, e até onde pude testá-lo, resolveu 100% meu problema:

    void Update()
    {

        perseguir();

        atacar();

        distancia = Vector3.Distance(transform.position, jogador.transform.position);

    }

    private void perseguir()
    {

        agente.SetDestination(jogador.position);

        animaChefe.AnimarMovimento(agente.velocity.magnitude);


    }

    private void atacar()
    {

        if (distancia < 5)
        {

            Vector3 direcao = jogador.position - transform.position;

            Rotacionar(direcao);

            animaChefe.Atacar(true);

            agente.enabled = false;


        } 
        else
        {

            animaChefe.Atacar(false);

            agente.enabled = true;

        }

    }

    private void AtacaJogador()
    {

        int dano = Random.Range(danoMin, danoMax);

        jogador.GetComponent<controlaJogador>().TomarDano(0);

    }

    public void Rotacionar(Vector3 direcao)
    {

        Quaternion novaRotacao = Quaternion.LookRotation(direcao);
        meuRigidbody.MoveRotation(novaRotacao);

    }

tentou desligar só a rotação com o updateRotation provavelmente vai funcionar beleza, aí quando tiver perto você desliga e longe liga de novo, parecido com o que você fez