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

Dúvida sobre movimentação do personagem

Boa Tarde professor, primeiramente gostaria de agradecer pelas excelentes aulas e parabenizar pela ótima didática.

Estou realizando um projeto para a faculdade de um jogo que mexe com Algoritmos de Escalonamento e a ideia é fazer algo parecido com o OverCooked (chamamos de OverClocked haha), e diferente da movimentação do jogo de zumbi que segue a colisão do raio, o personagem deve se mover e rotacionar apenas na direção em que o jogador virar através do w a s d, eu pesquisei e consegui fazer isso através do translate e rotate no código que irei mostrar, mas estou com aquele problema do personagem ficar tremendo ao colidir com o objeto.

Tentei arrumar da forma que você ensina no vídeo sobre colisões utilizando o RigidBody do jogador, mas como no código você está usando um Vector3 para criar a variável de direção e no meu eu não estou usando, eu não estou conseguindo separar o personagem apenas para andar pra frente e atrás e ao colidir ele não tremer, e caso andar no eixo horizontal ele apenas rotacionar, poderia me ajudar a entender como posso resolver isso?

Segue o código

    public class move : MonoBehaviour
{

    public float Velocidade = 10;
    public float Girar = 200;
    private Rigidbody rigidbodyJogador;

    void Start()
    {
        Time.timeScale = 1;
        rigidbodyJogador = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        float translate = (Input.GetAxis("Vertical") * Velocidade) * Time.deltaTime;
        //float eixoZ = Input.GetAxis("Vertical");
        float rotate = (Input.GetAxis("Horizontal") * Girar) * Time.deltaTime;

        //rigidbodyJogador.MovePosition(rigidbodyJogador.position + (translate * Velocidade * Time.deltaTime));

        transform.Translate(0, 0, translate);
        transform.Rotate(0, rotate, 0);
    }
}

Obrigado.

5 respostas

Oi, Christian, tudo bem?

Fico muito feliz que tenha gostado do curso e espero que goste das próximas partes :)

Você poderia criar o seu próprio Vector3, vou fazer um esboço de código abaixo pra ficar mais claro o que daria pra fazer:

void Update()
{
    float translateX = (Input.GetAxis("Horizontal");
    float translateZ = Input.GetAxis("Vertical");

    Vector3 movement = new Vector3(translateX, 0, translateZ);
        movement *= Velocidade * Time.deltaTime;

    rigidbodyJogador.MovePosition(rigidbodyJogador.position + (movement * Velocidade * Time.deltaTime));

    # Aqui poderia usar também o RigidBody
    transform.Rotate(0, translateX * Girar * Time.deltaTime, 0);
}

Fiz um código meio baseado no que já tinha no seu, mas acho que dá pra ter uma boa ideia sobre o que fazer. Eu escrevi ele direto aqui então pode ter algum errinho de sintaxe mas tiramos um pouco de dependência de executar o código diretamente assim fica mais fácil estender.

Assim nosso código fica mais maleável pra usar essa parte em múltiplos comportamentos.

Se ficar qualquer dúvida me avisa que mando um exemplo mais concreto.

Boa noite professor.

Eu acho que não entendi o exemplo direito, eu tentei criar o meu próprio Vector3 como no exemplo acima porem o Vector3 está prendendo o personagem no eixo X e Z apenas andando para frente e para trás, e rotacionando parado (seguindo o seu código a risca ele de lado enquanto rotaciona), então eu gostaria que você me mostrasse um exemplo mais concreto, e uma dúvida que surgiu, como eu estou usando o transform Translate e Rotate para realizar as movimentações eu gostaria de saber se há alguma forma de aplicar o RigidBody apenas dentro do transform.Translate pra não alterar na rotação porque acho que isso resolveria de alguma maneira.

Eu também pesquisei algumas opções nas bibliotecas como lookAt mas também não consegui implementar então não houve alterações no códigos que mostrei anteriormente porque ele funciona mas o personagem ainda treme.

Obrigado por responder e desculpa o incomodo com as dúvidas.

solução!

Olá Christian, estava querendo fazer a mesma coisa, vê se te ajuda, meu código ficou assim:

public float Velocity = 10;
Vector3 direction;
void Update()
    {
        direction = new Vector3(0, 0, Input.GetAxis("Vertical"));

        if (direction != Vector3.zero){ GetComponent<Animator>().SetBool("Moving", true); }
        else { GetComponent<Animator>().SetBool("Moving", false); }
    }
    private void FixedUpdate()
    {
        float v = Input.GetAxisRaw("Vertical");
        Vector3 tempVect = new Vector3(0, 0, v);
        if (tempVect != Vector3.zero)
        {
            if (v > 0)
            {
                GetComponent<Rigidbody>().MovePosition(transform.position + transform.forward * Velocity * Time.deltaTime);
            }
            else
            {
                GetComponent<Rigidbody>().MovePosition(transform.position + (transform.forward *-1) * Velocity * Time.deltaTime);
            }
        }
        GetComponent<Rigidbody>().rotation = Quaternion.Euler(GetComponent<Rigidbody>().rotation.eulerAngles + new Vector3(0f, Velocity * 15 * Input.GetAxis("Horizontal") * Time.deltaTime, 0f));
    }

É exatamente isso Iuri muito obrigado.

Eu devia ter pesquisado mais sobre os Quaternion porque não sabia desse Euler e nem da possibilidade de criar um Vector3 dentro do GetComponent, pelo visto tenho um longo caminho pela frente hehe.

Fala, pessoal, desculpa a demora. Fiquei feliz de ver outras pessoas respondendo :)

Vou deixar meu código aqui para consulta com alguns comentários, agora que entendi a movimentação que você queria fazer.

public class Movement : MonoBehaviour
{
    public float Velocidade = 10;
    public float Girar = 200;
    private Rigidbody rigidbodyJogador;

    void Start()
    {
        rigidbodyJogador = GetComponent<Rigidbody>();
    }

    // Fisica é importante colocar dentro do FixedUpdate
    void FixedUpdate()
    {
        float translate = (Input.GetAxis("Vertical") * Velocidade) * Time.deltaTime;
        float rotate = (Input.GetAxis("Horizontal") * Girar) * Time.deltaTime;

        // movimentacao
        rigidbodyJogador.MovePosition(rigidbodyJogador.position + (transform.forward * translate));

        //rotacao
        //criar um velor de rotação baseado todo zerado nos outros eixos 
        // mas com valor em Y baseado na tecla
        Vector3 rotation = transform.up * rotate;
        // Quaternion.Euler recebe um Vector3 mas retorna um Quaternion
        // a Unity usa Quarternion nas rotações
        Quaternion deltaRotation = Quaternion.Euler(rotation);

        // Interpolamos entre a rotação que estamos e a que queremos de forma suave
        rigidbodyJogador.MoveRotation(rigidbodyJogador.rotation * deltaRotation);
    }
}