Mover entidades
Cómo mover, rotar y escalar una entidad gradualmente a lo largo del tiempo, con cambios incrementales.
Para mover, rotar o cambiar el tamaño de una entidad en tu escena durante un periodo de tiempo, usa el Tween componente. El engine realiza la transformación deseada de forma suave, mostrando actualizaciones en cada frame hasta que termina la duración especificada. Además, los Transform valores del componente de la entidad afectada se actualizan en tiempo real en caso de que sea necesario hacer comprobaciones de proximidad en el código de la escena.
El componente Tween tiene las siguientes funciones:
setMove: Mover entre dos puntossetRotate: Rotar entre dos direccionessetScale: Escalar entre dos tamañossetMoveContinuous: Moverse constantemente en la misma direcciónsetRotateContinuous: Rotar constantemente en la misma direcciónsetTextureMove: Desplazar la textura de un material entre dos posicionessetTextureMoveContinuous: Desplazar la textura de un material constantemente en la misma dirección
Mover entre dos puntos
Para mover una entidad entre dos puntos, crea un Tween componente con la setMove .
const myEntity = engine.addEntity()
Transform.create(myEntity, {
position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(myEntity)
Tween.setMove(myEntity,
Vector3.create(1, 1, 1),
Vector3.create(8, 1, 8),
2000
)El tween de movimiento requiere la siguiente información:
entity: La entidad a moverstart: Un Vector3 para la posición inicialend: Un Vector3 para la posición finalduration: Cuántos milisegundos toma moverse entre las dos posiciones
Estos otros parámetros opcionales también están disponibles:
faceDirection: Si es true, la entidad se rota para mirar en la dirección del movimiento.easingFunction: Qué función de easing usar. Ver Non-linear tweens
Rotar entre dos direcciones
Para rotar una entidad entre dos puntos, crea un Tween componente con la setRotate .
El tween de rotación requiere la siguiente información:
start: Un Quaternion para la rotación inicialend: Un Quaternion para la rotación finalduration: Cuántos milisegundos toma moverse entre las dos posiciones
Este otro parámetro opcional también está disponible:
easingFunction: Qué función de easing usar. Ver Non-linear tweens
Rotar con un punto de pivote
Al rotar una entidad, la rotación siempre se hace en referencia a la coordenada central de la entidad. Para rotar una entidad usando otro conjunto de coordenadas como punto de pivote, crea una segunda entidad (invisible) con el punto de pivote como su posición y hazla padre de la entidad que quieres rotar.
Al rotar la entidad padre, sus hijos serán todos rotados usando la posición del padre como punto de pivote. Ten en cuenta que la position de la entidad hija está en referencia a la del padre.
Ten en cuenta que en este ejemplo, el sistema está rotando la pivotEntity entidad, que es padre de la childEntity entidad.
Escalar entre dos tamaños
Para cambiar la escala de una entidad entre dos tamaños, crea un Tween componente con su modo ajustado a Tween.Mode.Scale.
El tween de escala requiere la siguiente información:
start: Un Vector3 para el tamaño inicialend: Un Vector3 para el tamaño finalduration: Cuántos milisegundos toma moverse entre las dos posiciones
Este otro parámetro opcional también está disponible:
easingFunction: Qué función de easing usar. Ver Non-linear tweens
Non-linear tweens
Los tweens pueden seguir diferentes Easing Functions que afectan la tasa de cambio a lo largo del tiempo. Una linear función, significa que la velocidad del cambio es constante desde el inicio hasta el final. Hay muchas opciones para elegir, que trazan curvas de formas diferentes dependiendo de si el comienzo y/o el final empiezan lento, y cuánto. Una easeinexpo curva comienza lenta y termina rápida, incrementando la velocidad exponencialmente, por el contrario una easeoutexpo curva comienza rápida y termina lenta.
El opcional easingFunction parámetro toma su valor del EasingFunction enum, que ofrece las siguientes opciones:
EF_EASEBACKEF_EASEBOUNCEEF_EASECIRCEF_EASECUBICEF_EASEELASTICEF_EASEEXPOEF_EASEINBACKEF_EASEINBOUNCEEF_EASEINCIRCEF_EASEINCUBICEF_EASEINELASTICEF_EASEINEXPOEF_EASEINQUADEF_EASEINQUARTEF_EASEINQUINTEF_EASEINSINEEF_EASEOUTBACKEF_EASEOUTBOUNCEEF_EASEOUTCIRCEF_EASEOUTCUBICEF_EASEOUTELASTICEF_EASEOUTEXPOEF_EASEOUTQUADEF_EASEOUTQUARTEF_EASEOUTQUINTEF_EASEOUTSINEEF_EASEQUADEF_EASEQUARTEF_EASEQUINTEF_EASESINEEF_LINEAR
Rotación constante
Para hacer que una entidad rote constantemente, usa el Tween componente con la setRotateContinuous .
El tween de rotación continua requiere la siguiente información:
entity: La entidad a rotardirection: Un Quaternion para la rotaciónCambia la velocidad a la que se reproduce una animación cambiando la propiedad: Cuántos grados por segundo rotará la entidad
Este otro parámetro opcional también está disponible:
duration: Cuántos milisegundos sostener la rotación. Después de este tiempo, la rotación se detendrá.
Movimiento constante
Para hacer que una entidad se mueva constantemente en la misma dirección, usa el Tween componente con la setMoveContinuous .
El tween de movimiento continuo requiere la siguiente información:
entity: La entidad a moverdirection: Un Vector3 para el movimientoCambia la velocidad a la que se reproduce una animación cambiando la propiedad: Cuántos metros por segundo se moverá la entidad
Este otro parámetro opcional también está disponible:
duration: Cuántos milisegundos sostener el movimiento. Después de este tiempo, el movimiento se detendrá.
El tween de movimiento continuo requiere la siguiente información:
Secuencias de Tween
Para hacer que una entidad reproduzca una serie de tweens en secuencia, usa el TweenSequence componente. Este componente requiere dos campos:
sequence: Un array con múltiples definiciones de tween, que se ejecutarán secuencialmente. El array puede estar vacío, en cuyo caso solo reproduce el tween actual.loop(opcional): Si no se proporciona, la secuencia solo se reproduce una vez. Si el campo está presente, el valor debe ser un valor delTweenLoopenum. Los valores aceptados son:TL_RESTART: Cuando la secuencia termina, se reinicia. Si el último estado no coincide con el primer estado, la entidad salta instantáneamente de uno a otro.TL_YOYO: Cuando la secuencia termina, va hacia atrás, realizando todos los tweens en reversa hasta que alcanza el inicio nuevamente. Luego comienza otra vez.
Mover de ida y vuelta
Para hacer que una plataforma se mueva constantemente de ida y vuelta entre dos posiciones, deja el sequence array vacío, y establece loop a TweenLoop.TL_YOYO
La entidad se moverá de ida y vuelta entre el punto inicial y el punto final, con la misma duración y la misma función de easing en ambas direcciones.
Seguir un camino
Para hacer que una entidad siga un camino más complejo con múltiples puntos, proporciona una lista de definiciones de tween en la sequence de un TweenSequence componente.
Ten en cuenta que al definir un tween dentro de un TweenSequence, necesitas usar el formato más verboso de Tween.Mode.Move, o Tween.Mode.Rotate, o Tween.Mode.Scale para definir el tween. En este formato más verboso, necesitas especificar:
duration: Cuántos milisegundos toma moverse entre las dos posicioneseasingFunction: Qué función de easing usar. Ver Non-linear tweens. En este formato el valor es requerido.mode: El modo del tween, que puede serTween.Mode.Move,Tween.Mode.Rotate, oTween.Mode.Scale.
Y dentro del campo mode debes especificar:
start: El valor inicial del tweenend: El valor final del tween
Al finalizar un tween
Usa tweenSystem.tweenCompleted para detectar cuando un tween ha terminado. Esto puede ser útil para realizar acciones cuando un tween termina, por ejemplo para abrir una puerta de ascensor.
Tweens simultáneos
Una entidad solo puede tener un Tween componente, y cada componente tween solo puede realizar una transformación a la vez. Por ejemplo, no puedes hacer que una entidad se mueva lateralmente y además rote al mismo tiempo. Como solución alternativa, puedes usar entidades con parent. Por ejemplo, puedes tener una entidad padre invisible que se mueva lateralmente, con una hija visible que rote.
En el siguiente fragmento, una entidad padre rota mientras una hija aumenta su escala.
Pausar un tween
Para pausar un tween, cambia la detiene todas las demás animaciones que la entidad está reproduciendo actualmente. Para reproducir múltiples animaciones al mismo tiempo, modifica manualmente la propiedad propiedad a false. Para reanudarlo, cámbiala de nuevo a true.
Para terminar un tween que no necesita ser continuado, elimina el Tween componente de la entidad. Si la entidad también estaba usando un TweenSequence componente, elimínalo también.
Tweens basados en un sistema
En lugar de usar el componente Tween y dejar que el engine maneje la transformación, puede que prefieras hacer esta transición de forma incremental, frame por frame, vía un system en tu escena. Moviendo la entidad una pequeña cantidad cada vez que la función se ejecuta.
Por un lado, esto te da más control para recalcular movimientos en cada frame. Por otro lado, el código es más complicado, y los jugadores con máquinas menos potentes podrían experimentar el tween como entrecortado, notando cada incremento.
Mover vía system
La forma más fácil de mover una entidad es modificar gradualmente el position valor almacenado en el Transform componente.
En este ejemplo estamos moviendo una entidad 0.1 metros por tick del game loop.
Vector3.Forward() retorna un vector que apunta hacia adelante y mide 1 metro de longitud. En este ejemplo luego escalamos este vector a 1/10 de su longitud con Vector3.scale(). Si nuestra escena tiene 30 frames por segundo, la entidad se está moviendo a 3 metros por segundo de velocidad.

Rotar vía system
La forma más fácil de rotar una entidad es cambiar gradualmente los valores en el componente Transform de forma incremental, y ejecutar esto como parte de la función de un system.
Ten en cuenta que para combinar la rotación actual con cada incremento, estamos usando Quaternion.multiply. En matemática de quaterniones, combinas dos rotaciones multiplicándolas, NO sumándolas. La rotación resultante de multiplicar un quaternion por otro será la rotación final equivalente tras realizar primero una rotación y luego la otra.
En este ejemplo, estamos rotando la entidad 1 grado en dirección hacia arriba en cada tick del game loop.

Rotar vía system sobre un punto de pivote
Al rotar una entidad, la rotación siempre se hace en referencia a la coordenada central de la entidad. Para rotar una entidad usando otro conjunto de coordenadas como punto de pivote, crea una segunda entidad (invisible) con el punto de pivote como su posición y hazla padre de la entidad que quieres rotar.
Al rotar la entidad padre, sus hijos serán todos rotados usando la posición del padre como punto de pivote. Ten en cuenta que la position de la entidad hija está en referencia a la del padre.
Ten en cuenta que en este ejemplo, el sistema está rotando la pivotEntity entidad, que es padre de la childEntity entidad.

Ajustar movimiento al tiempo de retardo
Supón que el jugador que visita tu escena tiene dificultades para seguir el ritmo del frame rate. Eso podría resultar en que el movimiento parezca entrecortado, ya que no todos los frames están uniformemente temporizados pero cada uno mueve la entidad en la misma cantidad.
Puedes compensar este desfase en el tiempo usando el dt parámetro para ajustar la escala del movimiento.
El ejemplo anterior mantiene el movimiento aproximadamente a la misma velocidad que el ejemplo de movimiento anterior, incluso si el frame rate baja. Cuando se ejecuta a 30 frames por segundo, el valor de dt es 1/30.
También puedes suavizar rotaciones de la misma manera multiplicando la cantidad de rotación por dt.
Mover entre dos puntos vía system
Si quieres que una entidad se mueva suavemente entre dos puntos, usa el lerp (interpolación lineal) algoritmo. Este algoritmo es muy conocido en desarrollo de juegos, ya que es realmente útil.
El lerp() la función toma tres parámetros:
El vector para la posición de origen
El vector para la posición objetivo
La cantidad, un valor de 0 a 1 que representa qué fracción de la traducción realizar.
El algoritmo de interpolación lineal encuentra un punto intermedio en el camino entre ambos vectores que coincide con la cantidad provista.
Por ejemplo, si el vector de origen es (0, 0, 0) y el vector objetivo es (10, 0, 10):
Usar una cantidad de 0 devolvería (0, 0, 0)
Usar una cantidad de 0.3 devolvería (3, 0, 3)
Usar una cantidad de 1 devolvería (10, 0, 10)
Para implementar esto lerp() en tu escena, recomendamos crear un custom component para almacenar la información necesaria. También necesitas definir un sistema que implemente el movimiento gradual en cada frame.

Rotar entre dos ángulos vía system
Para rotar suavemente entre dos ángulos, usa el slerp (esférica (interpolación) lineal). Este algoritmo es muy similar a un lerp, pero maneja rotaciones en quaternion.
El slerp() la función toma tres parámetros:
El quaternion ángulo para la rotación de origen
El quaternion ángulo para la rotación objetivo
La cantidad, un valor de 0 a 1 que representa qué fracción de la traducción realizar.
Para implementar esto en tu escena, recomendamos almacenar los datos que entran en la Slerp() función en un custom component. También necesitas definir un sistema que implemente la rotación gradual en cada frame.
📔 Nota: En su lugar podrías representar la rotación con ángulos euler como Vector3 valores y usar una Lerp() función, pero eso implicaría una conversión desde Vector3 a Quaternion en cada frame. Los valores de rotación se almacenan internamente como quaterniones en el Transform componente, por lo que es más eficiente para la escena trabajar con quaterniones.

Un enfoque más simple pero menos eficiente aprovecha la Quaternion.rotateTowards función, y evita usar cualquier componente personalizado.
En el ejemplo anterior Quaternion.rotateTowards toma tres argumentos: la rotación inicial, la rotación final deseada y el incremento máximo por frame. En este caso, dado que el incremento máximo es de dt * 10 grados, la rotación se realizará durante un periodo de un par de 9 segundos.
Ten en cuenta que el sistema también comprueba si la rotación está completa y si es así elimina el system del engine. De otro modo, el sistema seguiría haciendo cálculos en cada frame, incluso una vez la rotación esté completa.
Cambiar escala entre dos tamaños vía system
Si quieres que una entidad cambie de tamaño suavemente y sin cambiar sus proporciones, usa la lerp (interpolación lineal) algoritmo de la Scalar objeto.
De lo contrario, si quieres cambiar los ejes en diferentes proporciones, usa Vector3 para representar la escala de origen y la escala objetivo, y luego usa la lerp función del Vector3.
El lerp() función del Scalar objeto toma tres parámetros:
Un número para la escala de origen
Un número para la escala objetivo
La cantidad, un valor de 0 a 1 que representa qué fracción del escalado realizar.
Para implementar este lerp en tu escena, recomendamos crear un componente personalizado para almacenar la información necesaria. También necesitas definir un sistema que implemente el escalado gradual en cada frame.

Moverse a velocidades irregulares entre dos puntos vía system
Mientras usas el método lerp, puedes hacer que la velocidad de movimiento sea no lineal. En el ejemplo anterior incrementamos la cantidad de lerp por una cantidad dada en cada frame, pero también podríamos usar una función matemática para aumentar el número exponencialmente u otras medidas que te den un ritmo de movimiento diferente.
También podrías usar una función que dé resultados recurrentes, como una función seno, para describir un movimiento que va y viene.
A menudo estas transiciones no lineales pueden dar mucha vida a una escena. Un movimiento que se acelera siguiendo una curva o que se desacelera gradualmente puede decir mucho sobre la naturaleza de un objeto o personaje. Incluso podrías aprovechar funciones matemáticas que añadan efectos de rebote.
El ejemplo anterior es igual al ejemplo de lerp lineal que hemos mostrado antes, pero el fraction campo mapeado a un valor no lineal en cada tick. Este valor no lineal se usa para calcular la lerp function, resultando en un movimiento que sigue una curva exponencial.
También puedes mapear una transición en rotación o en escala de la misma manera que se muestra arriba, mapeando una transición lineal a una curva.

Seguir un camino vía system
Puedes hacer que una entidad recorra un array de vectores, realizando un movimiento lerp entre cada uno para seguir un camino más complejo.
El ejemplo anterior define un camino 3D compuesto por cuatro vectores 3D. El PathTransportData custom component holds the same data used by the custom component in the lerp example above, but adds a path array, with all of the points in our path, and a pathTargetIndex campo para llevar la cuenta de qué segmento del camino se está usando actualmente.
El system es muy similar al system en el lerp example, but when a lerp action is completed, it sets the target y origin campos a nuevos valores. Si llegamos al final del camino, volvemos al primer valor del camino.

Tween de texturas
Para hacer que una textura se deslice suavemente, usa el Tween componente con la setTextureMove .
El tween de textura toma la siguiente información:
entity: La entidad cuya textura se moverástart: Un Vector2 para la posición inicialend: Un Vector2 para la posición finalduration: Cuántos milisegundos toma moverse entre las dos posiciones
Este otro parámetro opcional también está disponible:
movementType: (opcional), define si el movimiento será sobre el campo offset o el campo tiling. Por defecto usa offset.easingFunction: Qué función de easing usar. Ver Non-linear tweens. Nota: Este parámetro solo se usa si se proporciona una duración.
Movimiento constante de textura
Para hacer que una textura se deslice constantemente, usa el Tween componente con la setTextureMoveContinuous .
El tween continuo de textura toma la siguiente información:
entity: La entidad cuya textura se moverádirection: Un Vector2 para el movimientoCambia la velocidad a la que se reproduce una animación cambiando la propiedad: Cuántas unidades por segundo se moverá la entidad
Este otro parámetro opcional también está disponible:
movementType: define si el movimiento será sobre el campo offset o el campo tiling. Por defecto usa offset.duration: Cuántos milisegundos sostener el movimiento. Después de este tiempo, el movimiento se detendrá.
Lee más sobre los tween de textura en el Texture Tweens sección.
Última actualización