Logra colisiones sólidas y un movimiento fluido en Unity 2D con una configuración correcta de colliders y Rigidbody2D. Aquí verás cómo cerrar el nivel con límites invisibles, desactivar la gravedad, evitar giros indeseados y migrar el control del personaje de Translate a velocity para aprovechar el motor de físicas.
¿Cómo crear fronteras con colliders en el nivel?
Para impedir que el personaje salga del escenario, se construyen límites invisibles con BoxCollider2D alrededor del mapa. Esto evita “atravesar” bordes cuando todavía no hay obstáculos naturales como árboles.
Crea un GameObject vacío llamado “Boundary”.
Añade cuatro hijos: “North”, “South”, “West” y “East”.
En cada hijo, agrega un BoxCollider2D.
Ajusta posición y tamaño hasta cubrir cada borde del nivel.
Prioriza escalar el collider en lugar del GameObject.
¿Cómo nombrar y posicionar los límites?
North: colócalo en el borde superior del mapa.
South: duplica North y muévelo al borde inferior.
West: centra en Y y estira el collider a lo alto.
East: duplica West y muévelo al borde derecho.
¿Qué errores evitar al ajustar colliders?
No busques precisión milimétrica: un cuadrado de más no afectará.
Evita escalar el GameObject si el collider puede escalarse mejor.
Comprueba el “enganche” visual con el tile set del nivel.
¿Cómo configurar Rigidbody2D para colisiones sin gravedad?
El motor de físicas requiere que el personaje sea un cuerpo rígido. Sin Rigidbody2D, las colisiones no son reales y se atraviesa todo como “fantasma”. Al activarlo, hay que desactivar efectos no deseados como gravedad y torsión.
Agrega un Rigidbody2D al jugador.
Cambia gravity scale a 0 para que no caiga por gravedad.
Activa freeze rotation en Z para evitar giros al chocar.
Verifica que objetos del entorno tengan colliders.
¿Por qué se gira el personaje al chocar?
Por defecto, el Rigidbody2D permite torsión ante impactos.
Al congelar la rotación en Z, el sprite no se invierte al colisionar.
¿Qué mejoras notarás en las colisiones?
No atraviesas agua, árboles ni bordes.
Toques y empujes se resuelven físicamente.
Movimiento estable, sin volteos indeseados.
¿Cómo migrar de Translate a movimiento físico con velocity?
Si usas físicas, evita Transform.Translate y mueve con Rigidbody2D.velocity. Así las colisiones y la fricción se comportan correctamente. Además, ajusta la velocidad porque ahora interviene la masa del cuerpo.
Comenta la línea de Translate en el controller.
Declara e inicializa una referencia a Rigidbody2D.
Actualiza la velocity con los ejes de entrada.
Frena en seco cuando no caminas para evitar “patinar”.
¿Qué cambios de código aplicar?
// Debajo del AnimatorprivateRigidbody2D playerRigidbody;voidStart(){ playerRigidbody =GetComponent<Rigidbody2D>();}voidUpdate(){// Horizontal: conserva Y playerRigidbody.velocity =newVector2( Input.GetAxisRaw("Horizontal")* speed * Time.deltaTime, playerRigidbody.velocity.y
);// Vertical: conserva X playerRigidbody.velocity =newVector2( playerRigidbody.velocity.x, Input.GetAxisRaw("Vertical")* speed * Time.deltaTime
);// Si no camina, frenar en secoif(!walking){ playerRigidbody.velocity = Vector2.zero;}}
¿Cómo ajustar velocidad, masa e inercia?
La velocidad percibida depende de la masa del Rigidbody2D.
Opciones: bajar masa o subir el parámetro speed.
Sugerencia práctica: incrementa speed (por ejemplo, 100–120) hasta sentir control preciso.
Con el frenado en seco, desaparece el efecto de patinar.
¿Qué conceptos y habilidades pones en práctica?
Uso de colliders para límites del mapa.
Configuración de Rigidbody2D con gravity scale y freeze rotation.
Migración de Transform.Translate a Rigidbody2D.velocity.
Entrada con Input.GetAxisRaw y tiempo con Time.deltaTime.
Control de inercia con Vector2.zero.
Organización de escena: objetos vacíos, hijos y duplicados.
¿Te quedó alguna duda sobre Rigidbody2D, colliders o el movimiento con velocity? Comparte tu pregunta o tu código en los comentarios y lo revisamos juntos.
Para los que tengan problemas con su movimiento del personaje (se mueve raro, algo brusco o acelera de vez en cuando) el problema esta en el Input.GetAxisRaw(horizontal) * speed * Time.deltaTime;
El hecho es de que ese Time.deltaTime no deberia de estar ahi dado a que ya no es distancia = velocidad * tiempo, sino solo necesitamos de la velocidad del mismo, en este caso "speed". Quedaria asi:
Input.GetAxisRaw(horizontal) * speed;
Asi mismo, debes de cambiarlo para la vertical:
Input.GetAxisRaw(vertical) * speed;
Me sirvió tu solución. A mi me pasaba que se movía muy lento a pesar que le subía demasiado a la velocidad y le bajaba toda la masa.
Hola Juan/Comunidad, vi varias veces el video y tengo todo igual pero el personaje quedo raro después de que le agregamos las físicas. Y en cuanto a raro me refiero a que si estas caminando verticalmente (W o flecha para arriba) y aprietas rápidamente y sin soltar la (D o flecha para la derecha) y luego sueltas la (W o flecha para arriba) sigue caminando en diagonal, cuando tendría que caminar solamente para la derecha. Reverse los cambios hasta antes de agregarle el rígidobodies y funciona como describo anteriormente, porfavor su ayuda en esto.
Raro, podrías subir screenshots?
Hola Ricardo, muchas gracias por contestar, la verdad que en una simple imagen no podrías ver lo que te digo, grabe un video de segundos y lo subí a internet lo dejare en este comentario para que lo puedas ver. Si te fijas el personaje constantemente va en diagonal y yo no estoy apretando las 2 teclas para que lo haga.
Antes que nada muchas gracias!
video
Les quisiera aportar a ustedes, queridos compañeros estudiantes, una buena practica en el uso del Update:
Usen el Update para recibir los inputs y todo lo que venga de parte del jugador. Usen el FixedUpdate para implementar todo lo relacionado al RB (rigidbody) y otras fisicas. Y finalmente, usen el LateUpdate para las animaciones. Estas buenas practicas ayudaran al motor de Unity.
les estaria quedando algo asi...
Update() { INPUTS }
FixedUpdate() { RB y FISICAS }
LateUpdate() { ANIMACIONES }
Lo de las animaciones en el LateUpdate no se si aplica como tu lo describes. El LateUpdate se ejecuta luego del Animators.Update por lo que en el momento que se ejecuta el LateUpdate ya se actualizo el estaod de las animaciones. Seria util para chequear el estado actual en el que se encuentra el Animator pero para lo demas yo creo que es mejor el Update que ocurre antes del Animators.Update (todo esto lo puedes comprobar con el profiler)
Por si alguien no hizo un mapa completamente cuadrado y necesita otra forma de colocar los colliders, pueden hacer dos capas mas en la grid, una que sea Sea Collider y otra que sea Sea solo, hacer una linea en los bordes con agua, y luego pintar agua debajo y mas alla de la linea del sea collider.
No es aconsejable colocarle Collider a todo lo que sea Sea porque son realmente un monton de colliders que deben renderizarse al mismo tiempo.
Una forma alternativa es usar un Edge Collider, cuya forma pueden ir moldeando y quedaran los limites trazados dependiendo de la precision de su tiempo libre. 😅
En lo personal, le di un margen al terreno con arboles que agregue a la capa foreground(En mi caso le di el nombre de collisions), ademas de tener un pequeño espacio para que simule una continuidad de bosque y no se vea un fondo oscuro o de un color que va fuera del contexto del juego.
Aunque realmente, no se si esto de problemas con la optimización
ahí esta mi progreso hasta ahora :D
Buenas cuando mi personaje camina como que se acelera un poco o como si se teletransportara, como corregir este bug sin quitar el Time.DeltaTime como sugirieron (pues entiendo que es una mala idea para cuando uno cambia de computadora el juego)?
Hola me pasa algo muy raro y es que cuando mi personaje camina como que se acelera un poco o como si se teletransportara alguien sabe como corregir este bug?
Hola, hum.. el problema esta en lo que seria el script, para ser mas especificos, en la parte playerRigidbody.velocity = new Vector2( Input.GetAxisRaw(horizontal) * speed * Time.deltaTime, playerRigidbody.velocity.y). Debes de borrarle el " * Time.deltaTime " y se solucionara. Asi mismo, debes borrarlo en el vertical
Hola! de pronto alguien sabe por que me volvieron a aparecer lineas azules verticales cuando corro el juego? ya tiene aplicado el fix con el material en las capas de la grid, pero volvieron a salir :(
Otra duda, si venimos manejando vectores 3D porr que cambiamos a vectores 2d? Entiendo que el juego es 2D y la velocidad en Z siempre se mantendra en 0, pero anteriormente se ha mencionado que a pesar de eso, se debe considerar la Z.
La cuestion es ¿En que caso debemos usar vector3 y en cual vector2?
Hola Ricardo, usamos vectores 3D para lo que es movimiento, porque si bien estamos usando X e Y el motor es en 3D y por eso colocamos Z con 0. En cambio con la velocidad usamos vectores 2D porque nuestro rigidBody es 2D, entonces no necesitamos de la Z. Espero que te sea de ayuda :D
¿Por que razón seria mejor usar las físicas que usamos para las colisiones en lugar translate, siendo translate más fácil de programar?
Me contesto a mi 6 meses despues:
Porque al trasladar el objeto se mueve sin tener en cuenta las fisicas, por lo que al haber colisiones frente a el, estas no podrian ser detectadas.
Translate: No detecta colisiones
Fisicas2D: Detecta colisiones
De causalidad saben porque el personaje se ve como si estuviera chocando constantemente contra algo a la hora de moverse?
Vi que la velocidad en la que el personaje se movia era diferente porque se esta usando el Update() e intente usando el FixedUpdate() pero la verdad es que se ve aun peor el personaje vibra horrible hasta el punto de verse borroso, cosa que no notaba con el Translate().
me sucede lo mismo
En lo personal, prefiero mantenerme con el translate que resulta mejor en cuanto a programación y errores.
No hay que incrementar la velocidad, sino que se aplico la misma lógica del Transform.Translate al rigid.velocity.
El primero traslada al objeto cada frame, y el segundo asigna una velocidad en m/s.
El Time.deltaTime es el valor de 1 dividido para los cuadros por segundo.
Este es un valor fraccionario que en el caso de que sean 60 es de 0.0166.
Esto es útil para la primera opción pero no para rigid.velocity. Yo opte por no multiplicar la velocidad por Time.deltaTime y no tuve que aumentarle la velocidad para tener el mismo efecto.
Si no multiplicas por time.Deltatime en computadoras potentes vas a tener un personaje volador jajajaja
Por mi parte, si quieres que la velocidad sea mas "Constante" en vez de usar Update puedes usar FixedUpdate que te garantiza 30 Frames por segundo sea cual sea el caso.
Yo tuve que ponerle 1700 de speed y 0.5 en masa para que no se moviera lento.
Wtf A mi con la velocidad original 4 se me mueve chido.
El problema es el time.deltaTime. Cambia el movimiento al FixedUpdate y no pongas el time.deltatime y con 4 va a nadar bien
Genial
yo solo hice una capa para colliders y ya me evite crear los gameobjets
Que tal, alguien sabe porque tengo este error?
NullReferenceException: Object reference not set to an instance of an object Unity Editor.EyeDropper.End()(at C:/buildslave/unity/Editor/Mono/GUI/ColorPiker.cs1268)
Lo pude "Solucionar", deseleccionando al "Player", pero esa no es la solucion correcta y me gustaría saber porque ocurre
Lo hice de esta forma tomando en cuenta las clases que hemos visto en los cursos anteriores. En translate creo que es necesario usar deltaTime pero no con el rigibody, son formulas distintas al parecer y va mas rápido con la velocidad en 4 si no aplicamos el deta.Time.