For the complete documentation index, see llms.txt. This page is also available as Markdown.

Mover Entities

Cómo mover, rotar y escalar una entidad gradualmente con el tiempo, con cambios incrementales.

Para mover, rotar o redimensionar una Entity en tu scene durante un periodo de tiempo, usa el Tween component. 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 component 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 scene.

💡 Consejo: En el Scene Editor in Creator Hub, puedes mover entidades sin código mediante Actions, consulta Hacer inteligente cualquier item.

El component Tween tiene las siguientes funciones:

  • setMove: Mover entre dos puntos

  • setRotate: Rotar entre dos direcciones

  • setScale: Escalar entre dos tamaños

  • setMoveRotateScale: Transicionar simultáneamente en los tres parámetros

  • setMoveContinuous: Moverse constantemente en la misma dirección

  • setRotateContinuous: Rotar constantemente en la misma dirección

  • setTextureMove: Desplazar la textura de un material entre dos posiciones

  • setTextureMoveContinuous: 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 component con la setMove función.

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 toma la siguiente información:

  • entity: La entidad a mover

  • start: Un Vector3 para la posición inicial

  • end: Un Vector3 para la posición final

  • duration: Cuántos milisegundos tarda en moverse entre las dos posiciones

También está disponible este otro parámetro opcional:

Rotar entre dos direcciones

Para rotar una entidad entre dos puntos, crea un Tween component con la setRotate función.

El tween de rotación toma la siguiente información:

  • start: Un Quaternion para la rotación inicial

  • end: Un Quaternion para la rotación final

  • duration: Cuántos milisegundos tarda en moverse entre las dos posiciones

También está disponible este otro parámetro opcional:

Rotar con un punto de pivote

Al rotar una entidad, la rotación siempre toma como referencia 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 haz que sea padre de la entidad que quieres rotar.

Al rotar la entidad padre, todas sus hijas se rotarán usando la posición del padre como punto de pivote. Ten en cuenta que la position de la entidad hija toma como referencia la de la entidad padre.

Ten en cuenta que en este ejemplo, el system está rotando la entidad pivotEntity que es padre de la entidad childEntity .

Escalar entre dos tamaños

Para cambiar la escala de una entidad entre dos tamaños, crea un Tween component con la setScale función.

El tween de escala toma la siguiente información:

  • start: Un Vector3 para el tamaño inicial

  • end: Un Vector3 para el tamaño final

  • duration: Cuántos milisegundos tarda en moverse entre las dos posiciones

También está disponible este otro parámetro opcional:

Mover desde la posición actual

Mientras un tween está activo, el engine actualiza los Transform valores del component de la entidad en tiempo real. Esto significa que puedes leer la posición actual de la entidad desde su Transform component en cualquier momento, y usar ese valor como el start de un nuevo tween. Entonces la entidad se mueve desde donde esté en ese momento hasta el destino, sin importar cómo llegó allí.

Cambiar el objetivo mientras viaja

Llamar a setMove (o a cualquiera de las otras funciones de tween) sobre una entidad que ya tiene un tween en ejecución reemplaza el tween en ejecución por el nuevo. Como la start se lee desde la posición en vivo de la entidad, esto redirige la entidad suavemente a mitad del viaje: cambia de rumbo desde donde está en ese momento, sin saltos.

El ejemplo de abajo mueve una entidad hacia la plataforma que el jugador haga clic. Si el jugador hace clic en otra plataforma mientras la entidad sigue viajando, la entidad cambia de dirección suavemente hacia el nuevo objetivo.

Para ejecutar lógica cuando la entidad llegue a su destino, consulta Al terminar el tween.

Tweens no lineales

Los tweens pueden seguir diferentes Easing Functions que afectan la tasa de cambio con el tiempo. Una lineal función significa que la velocidad del cambio es constante de principio a fin. Hay muchas opciones para elegir, que dibujan curvas con formas diferentes dependiendo de si el inicio y/o el final comienzan lento, y cuánto. Una curva easeinexpo comienza lenta y termina rápida, aumentando la velocidad exponencialmente; por el contrario, una curva easeoutexpo comienza rápida y termina lenta.

💡 Consejo: Experimenta con diferentes curvas de movimiento. Las diferencias suelen ser sutiles, pero interpretamos de forma subconsciente la información de cómo se mueven las cosas, como el peso, la fricción o incluso la personalidad.

El easingFunction parámetro opcional toma su valor de la EasingFunction enum, que ofrece las siguientes opciones:

  • EF_EASEBACK

  • EF_EASEBOUNCE

  • EF_EASECIRC

  • EF_EASECUBIC

  • EF_EASEELASTIC

  • EF_EASEEXPO

  • EF_EASEINBACK

  • EF_EASEINBOUNCE

  • EF_EASEINCIRC

  • EF_EASEINCUBIC

  • EF_EASEINELASTIC

  • EF_EASEINEXPO

  • EF_EASEINQUAD

  • EF_EASEINQUART

  • EF_EASEINQUINT

  • EF_EASEINSINE

  • EF_EASEOUTBACK

  • EF_EASEOUTBOUNCE

  • EF_EASEOUTCIRC

  • EF_EASEOUTCUBIC

  • EF_EASEOUTELASTIC

  • EF_EASEOUTEXPO

  • EF_EASEOUTQUAD

  • EF_EASEOUTQUART

  • EF_EASEOUTQUINT

  • EF_EASEOUTSINE

  • EF_EASEQUAD

  • EF_EASEQUART

  • EF_EASEQUINT

  • EF_EASESINE

  • EF_LINEAR

Rotación constante

Para hacer que una entidad rote constantemente, usa el Tween component con la setRotateContinuous función.

El tween de rotación continua toma la siguiente información:

  • entity: La entidad a rotar

  • direction: Un Quaternion que determina el eje alrededor del cual rotar. Solo importa el eje de esta rotación; el tamaño de su ángulo se ignora. Por ejemplo, Quaternion.fromEulerDegrees(0, -1, 0) y Quaternion.fromEulerDegrees(0, -90, 0) se comportan igual, ambos girando alrededor del eje y en dirección negativa.

  • speed: Cuántos grados por segundo rotará la entidad. Un valor negativo rota en la dirección opuesta.

También está disponible este otro parámetro opcional:

  • duration: Cuántos milisegundos debe mantenerse 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 component con la setMoveContinuous función.

El tween de movimiento continuo toma la siguiente información:

  • entity: La entidad a mover

  • direction: Un Vector3 para el movimiento

  • speed: Cuántos metros por segundo se moverá la entidad

También está disponible este otro parámetro opcional:

  • duration: Cuántos milisegundos debe mantenerse el movimiento. Después de este tiempo, el movimiento se detendrá.

El tween de movimiento continuo toma la siguiente información:

Seguir un objetivo en movimiento

setMoveContinuous también es la herramienta adecuada cuando el destino sigue cambiando, por ejemplo una entidad que sigue al jugador. Puede resultar tentador crear en su lugar un nuevo setMove tween en cada frame, apuntando a la última posición del jugador, pero eso produce un tirón visible.

La razón es que la posición que lees del Transform component de una entidad con tween es la posición que el engine informó por última vez a la scene, así que va con unos pocos frames de retraso respecto a dónde está realmente la entidad. Cuando pasas ese valor como el start de un nuevo tween, el engine lo aplica de inmediato y la entidad salta de vuelta a donde estaba hace unos pocos frames. Una de esas correcciones es imperceptible, pero repetirla muchas veces por segundo no lo es.

setMoveContinuous evita el problema por completo, porque le das una dirección y una velocidad en lugar de un punto de partida. El engine sigue usando la posición real de la entidad, así que reemplazar el tween para cambiar de dirección nunca hace que la entidad salte.

Secuencias de Tween

Para hacer que una entidad reproduzca una serie de tweens en secuencia, usa el TweenSequence component. Este component requiere dos campos:

  • sequence: Un array con múltiples definiciones de tween, que se ejecutarán secuencialmente. El array puede estar vacío; en ese 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 de la TweenLoop enum. Los valores aceptados son:

    • TL_RESTART: Cuando termina la secuencia, se reinicia. Si el último estado no coincide con el primero, la entidad salta instantáneamente de uno a otro.

    • TL_YOYO: Cuando termina la secuencia, retrocede, haciendo todos los tweens en orden inverso hasta volver a llegar al inicio. Luego comienza una vez más.

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 en 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 una ruta

Para hacer que una entidad siga una ruta más compleja con múltiples puntos, proporciona una lista de definiciones de tween en el sequence de un TweenSequence component.

Ten en cuenta que, al definir un tween dentro de un TweenSequence, necesitas usar el formato más detallado de Tween.Mode.Move, o Tween.Mode.Rotate, o Tween.Mode.Scale para definir el tween. En este formato más detallado, necesitas especificar:

  • duration: Cuántos milisegundos tarda en moverse entre las dos posiciones

  • easingFunction: Qué función de easing usar. Consulta Tweens no lineales. En este formato, el valor es obligatorio.

  • mode: El modo del tween, que puede ser Tween.Mode.Move, Tween.Mode.Rotate, o Tween.Mode.Scale.

Y dentro del campo mode field, necesitas especificar:

  • start: El valor inicial del tween

  • end: El valor final del tween

Al terminar el tween

Usa tweenSystem.tweenCompleted para detectar cuándo ha terminado un tween. Esto puede ser útil para realizar acciones cuando un tween finaliza, por ejemplo para abrir la puerta de un ascensor.

Tweens simultáneos

Para mover, rotar y escalar una entidad entre un estado inicial y uno final, crea una Tween component con la setMoveRotateScale función. Esta función también puede usarse en cualquier combinación de estos tres parámetros.

El tween de movimiento toma la siguiente información:

  • entity: La entidad a mover

  • params: Un objeto con los siguientes parámetros

    • position: (opcional) Un objeto con un start y end valor, ambos como Vector3.

    • rotation: (opcional) Un objeto con un start y end valor, ambos como Quaternion.

    • scale: (opcional) Un objeto con un start y end valor, ambos como Vector3. Al menos uno de position, rotation o scale debe proporcionarse.

    • duration: (obligatorio) Cuántos milisegundos tarda en transicionar entre los dos conjuntos de valores

    • easingFunction: (opcional) Qué función de easing usar. Consulta Tweens no lineales

Una entity solo puede tener un Tween component, y cada Tween component solo puede realizar una transformación a la vez. A través del setMoveRotateScale tipo de tween, puedes hacer que una entity se mueva lateralmente y también gire al mismo tiempo, pero ambos movimientos seguirán la misma línea de tiempo. Si necesitas que las transiciones sean independientes entre sí, como solución alternativa, puedes usar entities con parent. Por ejemplo, puedes tener una entity parent invisible que se mueve lateralmente, con una child visible que gira.

En el siguiente fragmento, una entity parent gira mientras una child se escala.

Pausar un tween

Para pausar un tween, cambia la playing propiedad a false. Para reanudarlo, vuelve a cambiarla a true.

Para terminar un tween que no necesita continuar, elimina el Tween component de la entity. Si la entity también estaba usando un TweenSequence component, elimina ese también.

Tweens basados en un system

En lugar de usar el Tween component y dejar que el engine se encargue de la transformación, quizá prefieras hacer esta transición de forma incremental, frame a frame, mediante un system en tu scene. Al mover la entity una pequeña cantidad cada vez que se ejecuta la función.

Por un lado, esto te da más control para recalcular los movimientos en cada frame. Por otro lado, el código es más complicado, y los players con máquinas menos potentes podrían experimentar el tween como lento, notando cada incremento.

Mover mediante system

La forma más sencilla de mover una entity es modificar gradualmente el position valor almacenado en la Transform component.

En este ejemplo estamos moviendo una entity 0,05 metros por tick del game loop.

Vector3.Forward() devuelve un vector que apunta hacia adelante y mide 1 metro de longitud. En este ejemplo luego reducimos este vector a 1/20 de su longitud con Vector3.scale(). Si nuestra scene tiene 30 frames por segundo, la entity se está moviendo a una velocidad de 1,5 metros por segundo.



Rotar mediante system

La forma más sencilla de rotar una entity es cambiar gradualmente los valores del Transform component 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 quaternion, 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 entity 1 grado en dirección ascendente en cada tick del game loop.

💡 Consejo: Para hacer que una entity gire siempre para mirar al player, puedes añadir un Billboard component.



Rotar mediante system sobre un punto de pivote

Al rotar una entidad, la rotación siempre toma como referencia 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 haz que sea padre de la entidad que quieres rotar.

Al rotar la entidad padre, todas sus hijas se rotarán usando la posición del padre como punto de pivote. Ten en cuenta que la position de la entidad hija toma como referencia la de la entidad padre.

Ten en cuenta que en este ejemplo, el system está rotando la entidad pivotEntity que es padre de la entidad childEntity .



Ajustar el movimiento al tiempo de retraso

Supón que el player que visita tu scene tiene dificultades para seguir el ritmo del frame rate. Eso podría hacer que el movimiento se vea entrecortado, ya que no todos los frames están espaciados uniformemente, pero cada uno mueve la entity la misma cantidad.

Puedes compensar este espaciado irregular 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 las rotaciones de la misma manera multiplicando la cantidad de rotación por dt.

Mover entre dos points mediante system

Si quieres que una entity se mueva suavemente entre dos points, usa el lerp (linear interpolation) algorithm. Este algorithm es muy conocido en el desarrollo de videojuegos, ya que es realmente útil.

El lerp() function toma tres parámetros:

  • El vector para la posición de origen

  • El vector para la posición de destino

  • La cantidad, un valor de 0 a 1 que representa qué fracción de la traslación realizar.

El algoritmo de interpolación lineal encuentra un punto intermedio en el recorrido entre ambos vectors que coincide con la cantidad proporcionada.

Por ejemplo, si el vector de origen es (0, 0, 0) y el vector de destino 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 scene, recomendamos crear un custom component para almacenar la información necesaria. También necesitas definir un system que implemente el movimiento gradual en cada frame.



Rotar entre dos ángulos mediante system

Para rotar suavemente entre dos ángulos, usa el slerp (esférica (linear interpolation) algorithm. Este algorithm es muy similar a un lerp, pero maneja rotaciones de quaternion.

El slerp() function toma tres parámetros:

  • El quaternion angle para la rotación de origen

  • El quaternion angle para la rotación de destino

  • La cantidad, un valor de 0 a 1 que representa qué fracción de la traslación realizar.

💡 Consejo: Puedes pasar valores de rotation en euler degrees (de 0 a 360) usando Quaternion.fromEulerDegrees().

Para implementar esto en tu scene, te recomendamos almacenar los datos que van a la Slerp() function en un custom component. También necesitas definir un system que implemente la rotación gradual en cada frame.



Un enfoque más simple, pero menos eficiente, aprovecha la Quaternion.rotateTowards function, y evita usar cualquier custom component.

En el example anterior Quaternion.rotateTowards takes three arguments: the initial rotation, the final rotation that's desired, and the maximum increment per frame. In this case, since the maximum increment is of dt * 10 degrees, la rotación se llevará a cabo durante un período de un par de 9 seconds.

Ten en cuenta que el system también comprueba si la rotación está completa y, si es así, elimina el system del engine. De lo contrario, el system seguiría haciendo cálculos en cada frame, incluso una vez que la rotación está completa.

Cambiar la scale entre dos sizes mediante system

Si quieres que una entity cambie de size suavemente y sin cambiar sus proportions, usa el lerp (linear interpolation) algorithm del Scalar object.

De lo contrario, si quieres cambiar los ejes en proporciones diferentes, usa Vector3 para representar la origin scale y la target scale, y luego usa la lerp function del Vector3.

El lerp() function del Scalar object toma tres parámetros:

  • Un number para la origin scale

  • Un number para la target scale

  • La cantidad, un valor de 0 a 1 que representa qué fracción del scaling realizar.

Para implementar este lerp en tu scene, te recomendamos crear un custom component para almacenar la información necesaria. También necesitas definir un system que implemente el escalado gradual en cada frame.



Mover a velocidades irregulares entre dos points mediante system

Mientras usas el método lerp, puedes hacer que la velocidad del movimiento sea no lineal. En el ejemplo anterior incrementamos la cantidad de lerp en una cantidad dada en cada frame, pero también podríamos usar una función matemática para aumentar el número exponencialmente o con 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 scene. Un movimiento que acelera a lo largo de una curve o desacelera gradualmente puede decir mucho sobre la nature de un object or character. Incluso podrías aprovechar funciones matemáticas que añadan efectos de rebote.

El ejemplo anterior es igual que el ejemplo de lerp lineal que hemos mostrado antes, pero el fraction campo se mapea a un valor no lineal en cada tick. Este valor no lineal se usa para calcular la lerp función, lo que da como resultado un movimiento que sigue una curva exponencial.

También puedes mapear una transición en rotation o en scale de la misma manera que se muestra arriba, mapeando una transición lineal a una curve.



Seguir un path mediante system

Puedes hacer que una entity recorra en loop un array de vectors, realizando un movimiento lerp entre cada uno para seguir un path más compleja.

El ejemplo anterior define un path 3D compuesto por cuatro vectors 3D. El PathTransportData custom component contiene los mismos datos usados por el custom component en el lerp example anterior, pero añade un path array, con todos los points de nuestro path, y un pathTargetIndex field para hacer seguimiento de qué segment del path está actualmente en use.

El system es muy similar al system del lerp example, pero cuando se completa una acción lerp, establece los target y origin fields con nuevos values. Si alcanzamos el end del path, volvemos al primer value del path.



Tweens de texture

Para hacer que una texture se deslice suavemente, usa el Tween component con la setTextureMove función.

El texture tween toma la siguiente information:

  • entity: La entity de la que mover la texture

  • start: Un Vector2 para la starting position

  • end: Un Vector2 para la ending position

  • duration: Cuántos milisegundos tarda en moverse entre las dos posiciones

También está disponible este otro parámetro opcional:

  • movementType: (opcional), define si el movement será en el field offset o el field tiling. Por defecto usa offset.

  • easingFunction: Qué función de easing usar. Consulta Tweens no lineales.

Movimiento constante de texture

Para hacer que una texture se deslice constantemente, usa el Tween component con la setTextureMoveContinuous función.

El texture continuous tween toma la siguiente information:

  • entity: La entity de la que mover la texture

  • direction: Un Vector2 para el movement

  • speed: Cuántas units per second se moverá la entity

También está disponible este otro parámetro opcional:

  • movementType: define si el movement será en el field offset o el field tiling. Por defecto usa offset.

  • duration: Cuántos milisegundos debe mantenerse el movimiento. Después de este tiempo, el movimiento se detendrá.

Lee más sobre texture tweens en la Texture Tweens section.

Última actualización