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!
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
Buenas y gracias por tu comentario!!!
Puedes decirme si tienes implementado algún otro tipo de control en el player? O has seguido tal cual mis tutoriales?
Gracias a ti por contestar!
He seguido tus tutoriales tal cual, y lo demás si que me funciona todo, mira te dejo un vídeo de lo que me pasa:
https://youtu.be/r2xZG-ftIPc
Mmmm, es un poco raro… puedes pasarme tu script?
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
De lujo, muchas gracias!
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
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
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;
}
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.
Hazme un favor, pasame por email los scripts de tu proyecto, o incluso si fuese posible, subelo entero a github y le echo un vistazo
gracias men ya solucione con la ayuda de Ulises… te agradezco
Genial! Me alegro de que ya lo hayas solucionado!
como puedo hacer que la plataforma rote ? en donde tengo que agregar las variables ?
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?
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!