Yo logre detener el movimiento del personaje llamado a un método de su RigidBody2D
rigid.Sleep ();
El personaje y el controlador
Introducción: De la idea al desarrollo
Estructura de carpetas en Unity
Assets, Game Objects y Sprite Atlas
Animaciones desde un sprite map
Animation Controller y Transiciones
Plataformas y gravedad
Física en Unity
El script de control
Programando funciones en C# y Unity: Jump
Detectar el suelo con Raycast
Herramientas de debugging visual
Cambiar las animaciones según los estados
Reto: Terminando nuestras animaciones
Solución del reto
Hacer que el personaje camine
El manager del videojuego
Cómo funciona el Game Manager
El Singleton
El modo de juego
Input manager y juegos multiplataforma
Corrección del Bug del salto
La zona de muerte
Reiniciar la partida
Corrigiendo los bugs al reiniciar nuestro juego
Diseño procedural de niveles 2D
El diseño de niveles a mano
Configurando nuestros assets para el diseño procedural
Generación procedural de niveles
Creando la zona que eliminará bloques del nivel excedentes
Añadir un nuevo bloque de forma aleatoria
La cámara que sigue al jugador
Destrucción de bloques antiguos
Terminando de programar la destrucción de bloques antiguos
Solucionando el salto de la cámara al reiniciar el juego
HUD, menús y gameplay
El canvas en Unity
Uso de botones para crear un menú
La lógica de los menús
Ejercicio: Preparando el menú del juego
Programando el menú del juego
Los coleccionables del juego
Actualizar UI de coleccionables
Iniciando con pociones y maná
Pociones de vida y maná
Programando las barras de vida y maná
Calculando los puntajes con la distancia y el tiempo de juego
La lógica del maná
Enemigos y dificultad
Plataformas móviles
Iniciar movimiento de la plataforma con trigger
Enemigos móviles
Enemigos móviles: preparando nuestro enemigo para girar
Enemigos móviles: programando que gire al chocar
Arreglando el collider de nuestra roca
Programando la condición de muerte del personaje
Añadiendo música de fondo a nuestro videojuego
Añadiendo efectos de sonido y cierre del curso
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Juan Gabriel Gomila
El Input Manager es una herramienta que nos proporciona Unity para expandir la entrada de controles y soportar y reaccionar correctamente a todas las posibles acciones de los jugadores en las plataformas disponibles. Unity nos enviará códigos especiales cuando el jugador oprima ciertos botones y nosotros devolveremos la acción que queremos realizar.
En esta clase vamos a trabajar con nuestros scripts controladores para cambiar entre los estados del juego por medio de esta nueva entrada de controles en vez de reaccionar por una tecla en particular.
El desafío de esta clase es evitar que nuestro personaje pueda saltar a menos que estemos en estado de ““In Game””, así como hemos evitado que nuestro personaje pueda avanzar en el resto de estados.
Aportes 29
Preguntas 3
Yo logre detener el movimiento del personaje llamado a un método de su RigidBody2D
rigid.Sleep ();
Mi código. Yo le tengo configurado para que no camine automáticamente, sino cuando yo presiono las flechas.
void Update () {
if(GameManager.sharedInstance.currentGameState == GameState.inGame){
if(Input.GetButtonDown("Jump")){
Jump();
}
}
animator.SetBool(STATE_ON_THE_GROUND, isTouchingTheGround());
Debug.DrawRay(this.transform.position, Vector2.down*1.4f, Color.red); // for debug purposes
}
void FixedUpdate() {
// if(rigidBody.velocity.x < runningSpeed){
// rigidBody.velocity = new Vector2(runningSpeed, rigidBody.velocity.y);
// }
if(GameManager.sharedInstance.currentGameState == GameState.inGame){
playerMovement();
}
}
void playerMovement(){
float isWalking = Input.GetAxisRaw("Horizontal");
if(isWalking != 0){ //is true
animator.SetBool(STATE_IS_QUIET, false);
animator.SetBool(STATE_IS_WALKING, true);
rigidBody.velocity = new Vector2(isWalking * runningSpeed,rigidBody.velocity.y);
spriteRenderer.flipX = (isWalking == -1) ? true : false;
//if the value returns -1 that means is walking to the left and we need to make a flip in X
}else{
animator.SetBool(STATE_IS_QUIET, true);
animator.SetBool(STATE_IS_WALKING, false);
}
}
Podemos encontrar la herramienta de Input Manager en Edit > Project Settings > Input
.
Solo hay que hacer eso para declarar que el personaje solo salte en modo juego, sin embargo al probarlo les recomiendo cambiar un momento la tecla de salto o intenten saltar con el mouse, ya que como tenemos designado que se cambie el estado del juego a inGame con la tecla Enter, unity me reconoce el spacebar tambien como enter, por ende al orpimir la barra espaciadora el personaje salta y me cambia el estado del juego automaticamente.
<if
(GameManager.sharedInstance.currentGameState == GameState.inGame) // solo puede saltar si esta en modo juego
{
if (Input.GetButtonDown("Jump")) //condicional para que se ejecute metodo jump al oprimir espacio o click derecho
{
Jump();
}
}>
Para los que lo están viendo en Diciembre 2021 la ruta es
Edit > Project Settings > Input Manager
Saludos. Activé el brinco solo si el estado del Juego está en “inGame”:
void Update()
{
if (GameManager.sharedInstance.currentGameState == GameState.inGame) {
if (Input.GetButtonDown("Jump")) { // Input manager action
Jump();
}
}
animator.SetBool(STATE_ON_THE_GROUND, IsTouchingTheGround());
}
por que me pasa que cuando presiono space mi game state cambia a ingame??
En el caso de que se quiera usar movimiento tanto horizontal como vertical controlado por el usuario. se debe usar la palabra “Horizontal” y “vertical” y para saber si es movimiento positivo o negativo, se debe usar el metodo GetAxisRaw.
// movimiento a la derecha
if(Input.GetButton("Horizontal") && Input.GetAxisRaw("Horizontal") > 0)
// movimiento a la izquierda
if(Input.GetButton("Horizontal") && Input.GetAxisRaw("Horizontal") < 0)
// movimiento hacia arriba
if(Input.GetButton("Vertical") && Input.GetAxisRaw("Vertical") > 0)
// movimiento hacia abajo
if(Input.GetButton("Vertical") && Input.GetAxisRaw("Vertical") < 0)
Yo lo solucione de esta forma
//saltara solo si se presiona la tecla designada por unity para el salto y si estamos en modo juego
if (Input.GetButtonDown("Jump") && Gamemanager.ShareInstance.currentGameState == GameState.inGame)
{
Jump();
}```
arregle el bug apagando el rigidbody en vez de modificando su velocidad, de esta manera no se ve afectado por las fisicas
En mi caso al teclear la barra espaciadora se iba a inGame porque en el input manager en el segundo submit lo tiene configurado con esa tecla
PlayerController:
void Update()
{
// Se gestionan las animaciones arriba para evitar bugs visuales in-game
anim.SetBool(STATE_GROUNDED, IsGrounded());
anim.SetBool(STATE_WALKING, rigidBody.velocity.x != 0);
// Se invierte este if para mejorar la legibilidad y reducir la complejidad cognitiva
if (GameManager.sharedInstanceGM.currentGameState != GameState.inGame) return;
if (Input.GetButtonDown("Jump"))
{
Jump();
}
Debug.DrawRay(this.transform.position - new Vector3(0, playerCollider.size.y / 2, 0), Vector2.down * gndRaycastLenght, Color.red);
}
void FixedUpdate()
{
// Se invierte este if para mejorar la legibilidad y reducir la complejidad cognitiva
if (GameManager.sharedInstanceGM.currentGameState != GameState.inGame) return;
float xAxis = Input.GetAxis("Horizontal");
if (xAxis != 0)
{
Walk(xAxis);
}
}
Finalmente se edita el Input Submit para que no se ejecute al presionar la barra espaciadora.
A mi me sale un error al tratar de cambiar el GameState.
Me sale este error:
NullReferenceException: Object reference not set to an instance of an object
Player_controler.FixedUpdate () (at Assets/Scripts/Player_controler.cs:46)
¿Qué debo de hacer?
copie lo mismo del profesor
if (GameManager.sharedInstance.currentGameState == GameState.inGame)
{
if (Input.GetButtonDown("Jump"))
{
Jump();
}
}
De hecho, al ver el juego en la primera clase ya imaginé cómo hacer los botones de juego
Solo hay que añadirle este if:
if (GameManager.sharedInstance.currentGameState == GameState.inGame)
A la función de getButtonDown(“jump”)
esat es mi solucion para JUMP
void Jump()
{
if(GameManager.sharedInstance.currentGameState == GameState.inGame)
{
if (IsTouchingTheGround()) //dependiendo del valor regresado del metodo, si es true pasara al salto
{
playerRB.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
}
}
}```
El salto no debería estar en el FixedUpdate?
Para congelar el personaje en el aire al poner pausa usé rigidBody.Sleep() dentro del PlayerController
private void FixedUpdate()
{
if(GameManager.sharedInstance.currentGameState == GameState.inGame)
{
if (rigidBody.velocity.x < runningSpeed)
{
rigidBody.velocity = new Vector2(runningSpeed, rigidBody.velocity.y);
}
} else
{
rigidBody.Sleep();
}
}
if (Input.GetButtonDown("Jump") && GameManager.SharedInstance.currentGameState == GameState.inGame)
{
Jump();
}
Lo mejor es de momento usar otra tecla para saltar y no el Space, porque esa tecla aparece como secundaria para el argumento “Jump”, así que al presionarla siempre va a saltar e inmediatamente va a cambiar a estado inGame. Ya luego de cambiar la tecla de salto se puede poner la condición if(GameManager.sharedInstance.currentGameState == GameState.inGame)
Ya sea en la propia función Jump() o en el Update.
Si alguien quiere implementar un menú de pausa este vídeo esta muy bueno.
https://www.youtube.com/watch?v=JivuXdrIHK0
Activar el auto completado del MonoDevelop es muy util
Este es el codigo de este video:
void FixedUpdate()
{
if (GameManager.sharedInstance.currentGameState == GameState.inGame)
{
if (rigidBody.velocity.x < runningSpeed)
{
rigidBody.velocity = new Vector2 (runningSpeed, rigidBody.velocity.y);
}
} else {
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
}
![](
Genial
Mi solución fue, primero como el profesor indica, los cambios a las fisicas los dejo en FixedUpdate, las entradas de datos como movimiento y jump los inclui en Update, asi que dejando fuera los estados de animación inserte una condicional para limitar el movimiento y el brinco a que solo sea en inGame, las animaciones iniciales las dejo fuera ya que al iniciar el juego en GameState.menu el player caía sin animación y con eso lo solucione
void Update()
{
animator.SetBool(STATE_ON_THE_GROUND, IsTouchingTheGround());
animator.SetBool(STATE_FALLING, IsFalling());
if (GameManager.sharedInstance.currentGameState == GameState.inGame)
{
if(Input.GetButtonDown("Jump"))
{
jumpKey = true;
}
move = Input.GetAxis("Horizontal");
if (move > 0)
{
spriteRenderer.flipX = false;
animator.SetBool(STATE_RUNNING, true);
}
else if (move < 0)
{
spriteRenderer.flipX = true;
animator.SetBool(STATE_RUNNING, true);
}
else
{
animator.SetBool(STATE_RUNNING, false);
}
}
else
{
jumpKey = false;
move = 0f;
}
Aqui mi código en FixedUpdate
void FixedUpdate()
{
if (jumpKey)
{
Jump();
jumpKey = false;
}
rigidBody.velocity = new Vector2(move * runningSpeed, //x
rigidBody.velocity.y); //y
}
Yo le deshabilite el animator también por que no me gustaba que terminará la animación
rigidBody.Sleep();
animator.enabled = false;
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?