Mover un enemigo en Unity con FixedUpdate garantiza una física estable y un movimiento suave, incluso si bajan los frames. Aquí verás cómo calcular la velocidad y el giro según la dirección, y cómo aplicar la velocidad al rigidbody solo cuando el juego está en marcha, para mantener un control total del comportamiento.
¿Por qué usar fixedupdate en Unity para física del enemigo?
Usar FixedUpdate evita que las caídas de FPS afecten al movimiento. A diferencia de Update, que corre cada frame, FixedUpdate se llama menos veces por segundo pero a intervalos fijos, ideal para cálculos de fuerzas, aceleraciones y velocidades que impactan el motor de físicas y los rigid bodies. Así se minimizan los cambios visuales indeseados en pantalla.
Update vs FixedUpdate: Update depende de los frames; FixedUpdate usa intervalos fijos.
Física estable: cálculos en FixedUpdate para evitar saltos visuales.
Cuándo usarlo: cuando actualizas el motor de físicas con velocidad o fuerzas.
Ejemplo de estructura básica:
voidFixedUpdate(){// 1) Calcular velocidad según dirección.// 2) Girar el sprite con eulerAngles si cambia la orientación.// 3) Aplicar la velocidad al rigidbody solo si el estado es InGame.}
¿Cómo calcular dirección y girar al enemigo con euler angles?
Primero se define una velocidad actual y se ajusta su signo según el sentido. Si mira a la derecha, es positiva; si mira a la izquierda, es negativa. Luego, se gira el objeto con transform.eulerAngles a 0 o 180 grados en el eje Y para reflejar visualmente el cambio de sentido.
¿Cómo invertir la velocidad según facing right?
Velocidad positiva: cuando se avanza a la derecha.
Velocidad negativa: cuando se avanza a la izquierda.
Variable clave: una float, por ejemplo, currentRunningSpeed.
¿Cómo aplicar la velocidad con gamemanager y rigidbody2d?
La velocidad calculada solo se aplica cuando el estado del juego es InGame. Si la partida no ha empezado o hay game over, el enemigo se queda quieto. Esto ofrece más control sobre el comportamiento y evita movimientos fuera de contexto.
Condición de movimiento: solo con GameState.InGame.
Eje X controlado: se usa currentRunningSpeed en X.
Eje Y preservado: se mantiene rb.velocity.y para no alterar su valor.
facingRight: al cambiarlo, el enemigo gira y recorre el lado opuesto.
runningSpeed: puedes subirlo para que vaya muy rápido.
Colocación en escena: si no está integrado en otros elementos, puede percibirse más lento respecto a la pantalla.
¿Te gustaría que el enemigo reaccione al chocar con paredes y se dé la vuelta de forma automática? Cuéntame qué comportamiento quieres añadir y lo diseñamos paso a paso.
También pueden usar esta línea de código para hacer el giro al sprite:
GetComponent<SpriteRenderer>().flipX = true;
Hay casos donde haya alguna diferencia en hacerlo de esta manera o de la que dijo el profe?
Es util si solo necesitas que el sprite se voltee (solo el sprite), pero en el caso de que por ejemplo tengas algun colisionador al lado derecho del gameObject, y no decees poner otro y por ende añadir otro script; lo mejor es hacerlo de la otra forma.
P.D.
Ademas del
Yo recomiendo una manera mas sencilla para voltearlo:
voidToFlip(){//Logica para determinar cuando voltea//Ejemploif(xDir <0&& facingRight ==true){Flip();}if(xDir >0&& facingRight ==false){Flip();}}//Funcion para voltearvoidFlip(){ facingRight =!facingRight;this.transform.localScale=newVector2(-transform.localScale.x, transform.localScale.y);}
FixedUpdate: se utiliza para actualizar el motor de física, con intervalos establecidos
Esta linea de codigo sirve para girar 180º:
this.transform.eulerAngles = new Vector3(0, 180, 0);
Dirección del enemigo{ rigidbody2D =GetComponent<Rigidbody2D>(); startPosition =this.transform.position;}// Start is called before the first frame updatevoidStart(){this.transform.position= startPosition;}privatevoidFixedUpdate(){ float currentRunnningSpeed = runningSpeed;if(movementDirection ==MovementDirection.horizontal){ rigidbody2D.constraints=RigidbodyConstraints2D.FreezePositionY;if(facingRight){ currentRunnningSpeed = runningSpeed;this.transform.eulerAngles=newVector3(0,180,0);}else{ currentRunnningSpeed =-runningSpeed;this.transform.eulerAngles=Vector3.zero;}}if(movementDirection ==MovementDirection.vertical){ rigidbody2D.constraints=RigidbodyConstraints2D.FreezePositionX;if(facingUp){ currentRunnningSpeed = runningSpeed;this.transform.eulerAngles=newVector3(0,0,-90);}else{ currentRunnningSpeed =-runningSpeed;this.transform.eulerAngles=newVector3(0,0,90);}}if(GameManager.sharedInstance.currentGameState==GameState.inGame){if(movementDirection ==MovementDirection.horizontal){ rigidbody2D.velocity=newVector2(currentRunnningSpeed, rigidbody2D.velocity.y);}if(movementDirection ==MovementDirection.vertical){ rigidbody2D.velocity=newVector2(rigidbody2D.velocity.x, currentRunnningSpeed);}}}}
Usaremos FixedUpdate(se ejecuta a intervalos fijos de tiempo) siempre que necesitemos el motor de físicas (fuerzas, aceleraciones, velocidades) - de esta manera evitaremos tener desfaces visuales.
¿Entonces podríamos decir entonces que utilizar el Delta Time y el método FixedUpdate() funcionarían igual en lo que a físicas se refiere?
Primero, hablemos de deltaTime. Esta es una medida de tiempo en segundos que representa el tiempo que ha pasado desde el último frame. Es esencial para hacer que tus juegos sean consistentes en diferentes dispositivos y velocidades de fotogramas. Al multiplicar valores como la velocidad del movimiento por Time.deltaTime, te aseguras de que el movimiento se realice de manera suave y constante, sin importar cuántos fotogramas se muestren por segundo.
Por otro lado, FixedUpdate es un método especial en Unity que se utiliza para realizar cálculos de física y movimiento en intervalos de tiempo fijos. A diferencia de Update, que se llama una vez por cada frame, FixedUpdate se llama a una tasa constante, generalmente cada 0.02 segundos por defecto. Esto es útil para evitar problemas de física en situaciones de alta velocidad de fotogramas, donde Time.deltaTime podría ser muy pequeño y causar comportamientos inconsistentes en el movimiento.
Entonces, en resumen, deltaTime se usa para hacer que el movimiento sea suave y dependiente del tiempo, mientras que FixedUpdate se utiliza para manejar cálculos de física y movimiento en intervalos de tiempo fijos, lo que ayuda a mantener la estabilidad en el juego. No son lo mismo, pero a menudo se usan juntos para lograr un control preciso en los juegos de Unity.