Tutorial Character Controller Unity 2019 | Moviendonos Junto a Plataformas y Objetos Moviles

En el video de Unity de hoy, aprenderemos a hacer que nuestro Character Controller se mueva junto a las plataformas móviles y cualquier superficie que se mueva debajo de el sin necesidad de triggers, haciendo uso del SphereCast para detectar la posición y rotación del suelo y calculando las posiciones pasadas para mover a nuestro personaje dependiendo del desplazamiento realizado.

No te pierdas ningún video de la serie de Unity del canal, y si tienes alguna duda, no dudes en dejar tu comentario!!

Codigo MoveWithFloor.cs :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Este script hacce que nuestro jugador se mueva junto al movimiento del suelo mientras esté isGrounded TRUE

public class MoveWithFloor : MonoBehaviour
{
    CharacterController player;  //Variable para almacenar el character controller
    Vector3 groundposition;      //Almacenamos la posicion actual del suelo
    Vector3 lastgroundposition;  //Almacenamos la ultima posicion conocida del suelo
    string groundName;           //Almacenamos el nombre actual del suelo
    string lastgroundName;       //Almacenamos el nombre del ultimo suelo conocido
    
    //Quaternion actualRot;
   // Quaternion lastRot;

    void Start()
    {
        player = this.GetComponent<CharacterController>(); //Inicializamos la variable player almacenando el componente CharacterController
    }
    
    void Update()
    {
        if (player.isGrounded)      //En casi de estar tocando el suelo
        {
            RaycastHit hit;         //Creamos una variable para almacenar la colision del RayCast

            if (Physics.SphereCast(transform.position, player.height / 4.2f, -transform.up, out hit))   //Y creamos una SphereCast, que es como un RayCast pero grueso, dandole un diametro y una direccion en la que "disparar" ese SphereCast
            {
                GameObject groundedIn = hit.collider.gameObject;    //Comprobmamos cual es el suelo actual y almacenamos su GameObject en una variable temporal
                groundName = groundedIn.name;                       //despues comprobamos el nombre del suelo
                groundposition = groundedIn.transform.position;     //Una vez que tenemos el GameObject localizado, almacenamos su posicion
                
                actualRot = groundedIn.transform.rotation;

                if (groundposition != lastgroundposition && groundName == lastgroundName)   //Si su posicion es distinta de la ultima posicion conocida y el nombre sigue siendo el mismo
                {
                    this.transform.position += groundposition - lastgroundposition; //Sumamos a nuestra posicion la diferencia entre la posicion actual del suelo y la ultimam posicion conocida del suelo.
               
                }

                if (actualRot != lastRot && groundName == lastgroundName) //hacemos que la roatcion del personaje se sincronize con la del suelo.
                {
                    var newRot = this.transform.rotation * (actualRot.eulerAngles - lastRot.eulerAngles);  //almacenamos los grados que hay de diferencia entre la rotacion actual y la ultima conozida de la plataforma, y lo multiplicamos por la rotacion del jugador
                    this.transform.RotateAround(groundedIn.transform.position , Vector3.up, newRot.y);     //ahora rotamos al jugador al rededor de la posicion de la plataforma, en el eje Y los grados almacenados en la anterior variable. 
                    
                }

                lastgroundName = groundName;        //Asignamos al ultimo suelo conocido, tanto el nombre como la posicion del suelo actual.
                lastgroundposition = groundposition; //asignamos la ultima posicion conocida de la plataforma
                lastRot = actualRot;                //asignamos la ultima rotacion conocida de la plataforma
               
            }
        }
        else if (player.isGrounded == false) //Si no estamos tocando el suelo reseteamos todas las variables a 0 para que no tengamos problemas al saltar estando en la plataforma.
        {
            lastgroundName = null;
            lastgroundposition = Vector3.zero;
            lastRot = Quaternion.Euler(0, 0, 0);
        }
        
    
    }

    //Aqui unicamente creamos un gizmo para poder comprobar si el diametro del SphereCast es adecuado al tamaño de nuestro jugador.
    private void OnDrawGizmos()
    {    
        player = this.GetComponent<CharacterController>();   
        Gizmos.DrawWireSphere(transform.position, player.height / 4.2f);
    }
}

Descarga el archivo pinchando AQUI!

17 comentarios en “Tutorial Character Controller Unity 2019 | Moviendonos Junto a Plataformas y Objetos Moviles”

  1. Hola buenas! Lo primero he seguido todo el tutorial y estoy muy contento con lo aprendido, lo haces muy bien, enhorabuena!

    Tengo un problemilla con este último vídeo, y es que la plataforma se mueve un poco mas rápido que el “player”, y al final cae, este ultimo va dando como saltitos, no está fijo en la plataforma, sabes que puede ser?¿

    Gracias de antemano

          • El Script es este tuyo que he descargado jeje, puede ser por el script de la plataforma?¿
            —————————————————————–
            public class PlatformController : MonoBehaviour
            {
            public Rigidbody platformRB;
            public Transform[] platformPositions;
            public float platformSpeed;

            private int actualPosition = 0;
            private int nextPosition = 1;

            public bool moveToTheNext = true;
            public float waitTime;

            void Update()
            {
            MovePlatform();
            }
            void MovePlatform()
            {
            if (moveToTheNext)
            {
            StopCoroutine(WaitForMove(0));
            platformRB.MovePosition(Vector3.MoveTowards(platformRB.position, platformPositions[nextPosition].position, platformSpeed * Time.deltaTime));
            }

            if (Vector3.Distance(platformRB.position, platformPositions[nextPosition].position) platformPositions.Length -1)
            {
            nextPosition = 0;
            }
            }
            }

            IEnumerator WaitForMove(float time)
            {
            moveToTheNext = false;
            yield return new WaitForSeconds(time);
            moveToTheNext = true;
            }
            }
            ———————————————————–

            Gracias por todo, si no ves el problema no te preocupes, ya buscare por otro lado.

          • Justo me está escribiendo otro suscriptor con el mismo problema.. voy a investigar a ver si puedo replicar el problema y puedo ayudaros a los dos

  2. hola buenas bro,yo tengo el mismo problema tengo mi propio control de jugador basado en el tuyo con pequeñas modificaciones ,pero al adaptar el script para moverme junto a las plataformas ,me pasa el mismo problema las plataformas avanzan un poco mas rapido que el personaje y termina callendo seguire investigando cual es mi problema y si logro solucionar lo informare aqui o en tu canal ,gracias bro si tienes alguna solucion estare pendiente

  3. hola bro, aqui estoy de nuevo ,para estar seguro que mi proyecto no es el del error al querer implementar la mecánica de seguir las plataformas, me di a la tarea de ver todos los tutoriales y seguir el curso ,pues ya termine y no conseguí hacer que el personaje se mueva junto con la plataforma hay una diferencia de distancia es decir la plataforma se mueve mas rápido que el personaje ,lo que me e dado cuenta es que si desactivo el script del player controller cuando estoy encima y la plataforma se mueve, consigo moverme junto con ella ,o comento la linea de codigo player.Move(movePlayer * Time.deltaTime); en el instante que estoy arriba tambien cosigo moverme creo que el player del characther controller esta reseteando la transform ,subi el proyecto a github para que puedas darle una revisada y ayudarnos a los que estamos en el mismo problema gracias y espero puedas ayudarme

    https://github.com/Biohazard9999/CHARACTHER-CONTROLLER

  4. hola,que tal aquí estoy de regreso encontré la solución después de investigar por días XD del problema que algunos tenemos al intentar seguir las plataformas resulta que el controlador de caracteres restablece su transformación directa. al hacer Los cambios de posición a la ubicación anterior esto no pasaba en versiones anteriores de Unity como en la que esta hecho el tutorial para los que tenemos versiones actuales ocurre esto con la funsion .move del caracther controller por lo consiguiente la solución es:

    buscar en el Script esta linea de código y agregar lo siguiente

    if (groudPosition != lastGroudPosition && groudName == lastGroundName)
    {

    this.transform.position +=groudPosition-lastGroudPosition;

    //Solucion
    player.enabled = false;
    player.transform.position = this.transform.position;
    player.enabled = true;

    }

  5. no he podido solucionar este problema en mi proyecto la plataforma no lleva mi personaje pero si pongo un gameObjet por ejemplo un cubo y le agrego el script de moverse con la plataforma, este si se va con la plataforma.
    si quito el componente character controller ami personaje mientras estoy sobre la plataforma en movimiento este si se mueve con ella, por lo que creo que mi problema esta en el script del player controller.

    estare pendienta si alguien me puede dar una solicion.

  6. Hola. Se que escribo ya pasado el tiempo y habrá nuevas versiones de Unity, pero me pasa lo mismo. Va un poco a trompicones y, al final, se cae. Mi script está copiado de esta misma página y añadiendo la solución escrita por Ulises García. Se mueve un poquitín a trompicones y cae. Y, efectivamente, si desactivo el CharacterController funciona bien. Incluso si desactivo el script de movimiento se mantiene sobre la plataforma. En cuando se activa, el player parece que se queda quieto (en realidad da unos pequeños saltitos), y cae.

    ¿Sabes algo nuevo sobre este temma?

  7. Buenas,

    Tengo el problema que seguí al completo los tutoriales y hasta ahora no había tenido problema. En este pasa que el jugador no se mueve con la plataforma por mucho que haga. He probado con la solución que comenta Ulises aquí y descargando el script pero tampoco.
    Estoy buscando pero no encuentro ninguna solución por Internet…

    Gracias!

Deja un comentario