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

Mover Entities

Cómo mover, rotar y escalar un entity gradualmente con el tiempo, con cambios incrementales.

Para mover, rotar o cambiar el tamaño de un entity en tu scene durante un período 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 valores del Transform component del entity afectado 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 en Creator Hub, puedes mover entities de una forma no-code mediante Actions, ver Haz cualquier item smart.

El componente 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: Mover constantemente en la misma dirección

  • setRotateContinuous: Rotar constantemente en la misma dirección

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

  • setTextureMoveContinuous: Desplazar la texture de un material constantemente en la misma dirección

Mover entre dos puntos

Para mover un entity entre dos puntos, crea un Tween component con el setMove function.

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: El entity que se va 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án disponibles estos otros parámetros opcionales:

  • faceDirection: Si es true, el entity se rota para mirar en la dirección del movimiento.

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

Rotar entre dos direcciones

Para rotar un entity entre dos puntos, crea un Tween component con el setRotate function.

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

Cuando rotas un entity, la rotación siempre se calcula con referencia a la coordenada central del entity. Para rotar un entity usando otro conjunto de coordenadas como punto de pivote, crea un segundo entity (invisible) con el punto de pivote como posición y haz que sea el padre del entity que quieres rotar.

Cuando se rota el entity padre, todos sus hijos se rotarán usando la posición del padre como punto de pivote. Ten en cuenta que la posición del entity hijo hace referencia a la del entity padre.

Ten en cuenta que en este ejemplo, el system está rotando el pivotEntity entity, que es un padre del childEntity entity.

Escalar entre dos tamaños

Para cambiar el scale de un entity entre dos tamaños, crea un Tween component con su mode establecido en Tween.Mode.Scale.

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:

Tweens no lineales

Los tweens pueden seguir distintos Easing Functions que afectan la velocidad del cambio a lo largo del tiempo. Una curva linear function, significa que la velocidad del cambio es constante de principio a fin. Hay muchas opciones para elegir, que dibujan curvas de distintas formas según si el inicio y/o el final empiezan despacio, y cuánto. Un easeinexpo empieza despacio y termina rápido, aumentando la velocidad exponencialmente; por el contrario, una curva easeoutexpo empieza rápido y termina despacio.

💡 Consejo: Experimenta con diferentes curvas de movimiento. Las diferencias suelen ser sutiles, pero interpretamos de forma subconsciente la información que transmiten los movimientos, como el peso, la fricción o incluso la personalidad.

El parámetro opcional easingFunction toma su valor del 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 un entity rote constantemente, usa el Tween component con el setRotateContinuous function.

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

  • entity: El entity que se va a rotar

  • direction: Un Quaternion para la rotación

  • speed: Cuántos grados por segundo rotará el entity

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

  • duration: Cuántos milisegundos mantener la rotación. Después de este tiempo, la rotación se detendrá.

Movimiento constante

Para hacer que un entity se mueva constantemente en la misma dirección, usa el Tween component con el setMoveContinuous function.

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

  • entity: El entity que se va a mover

  • direction: Un Vector3 para el movimiento

  • speed: Cuántos metros por segundo se moverá el entity

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

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

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

Secuencias de Tweens

Para hacer que un entity 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 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 del TweenLoop enum. Los valores aceptados son:

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

    • TL_YOYO: Cuando termina la secuencia, vuelve hacia atrás, haciendo todos los tweens en orden inverso hasta llegar de nuevo al inicio. Luego comienza una vez más.

Mover hacia adelante y hacia atrás

Para hacer que una plataforma se mueva constantemente hacia adelante y hacia atrás entre dos posiciones, deja el sequence array vacío, y establece loop a TweenLoop.TL_YOYO

El entity se moverá hacia adelante y hacia atrás 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 un entity siga una ruta más compleja con múltiples puntos, proporciona una lista de definiciones de tween en el sequence de un TweenSequence componente.

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, debes especificar:

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

  • easingFunction: Qué función de easing usar. Ver 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 debes especificar:

  • start: El valor inicial del tween

  • end: El valor final del tween

Al finalizar el tween

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

Tweens simultáneos

Para mover, rotar y escalar un entity entre un estado inicial y uno final, crea una Tween component con el setMoveRotateScale function. Esta función también se puede usar con cualquier combinación de estos tres parámetros.

El tween de movimiento toma la siguiente información:

  • entity: El entity que se va a mover

  • params: Un objeto con varios parámetros opcionales

    • posición: Un objeto con un start y end value, tanto como Vector3.

    • rotación: Un objeto con un start y end value, tanto como Quaternion.

    • escala: Un objeto con un start y end value, tanto como Vector3.

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

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

Un entity solo puede tener un Tween component, y cada component de tween solo puede realizar una transformación a la vez. A través del setMoveRotateScale tween type, puedes hacer que un entity se mueva lateralmente y también rote 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 un entity padre invisible que se mueva lateralmente, con un hijo visible que rote.

En el siguiente fragmento, un entity padre rota mientras un hijo escala hacia arriba.

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 del entity. Si el entity también estaba usando un TweenSequence component, elimina ese también.

Tweens basados en un system

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

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 con lag, notando cada incremento.

Mover mediante system

La forma más sencilla de mover un entity es modificar gradualmente el posición valor almacenado en el Transform componente.

En este ejemplo estamos moviendo un entity 0.1 metros por tick del game loop.

Vector3.Forward() devuelve un vector que apunta hacia delante y mide 1 metro de longitud. En este ejemplo, luego reducimos ese vector a 1/10 de su longitud con Vector3.scale(). Si nuestra scene tiene 30 frames por segundo, el entity se mueve a una velocidad de 3 metros por segundo.



Rotar mediante system

La forma más sencilla de rotar un entity es cambiar gradualmente los valores del component Transform de forma incremental, y ejecutar esto como parte de la function de un system.

Ten en cuenta que para combinar la rotación actual con cada incremento, estamos usando Quaternion.multiply. En la matemática de quaternions, combinas dos rotaciones multiplicándolas, NO sumándolas. La rotación resultante de multiplicar un quaternion por otro será la rotación final equivalente después de realizar primero una rotación y luego la otra.

En este ejemplo, estamos rotando el entity 1 grado hacia arriba en cada tick del game loop.

💡 Consejo: Para hacer que un entity rote siempre para mirar al player, puedes agregar un Billboard component.



Rotar mediante system sobre un punto de pivote

Cuando rotas un entity, la rotación siempre se calcula con referencia a la coordenada central del entity. Para rotar un entity usando otro conjunto de coordenadas como punto de pivote, crea un segundo entity (invisible) con el punto de pivote como posición y haz que sea el padre del entity que quieres rotar.

Cuando se rota el entity padre, todos sus hijos se rotarán usando la posición del padre como punto de pivote. Ten en cuenta que la posición del entity hijo hace referencia a la del entity padre.

Ten en cuenta que en este ejemplo, el system está rotando el pivotEntity entity, que es un padre del childEntity entity.



Ajustar el movimiento al tiempo de retraso

Supongamos que el player que visita tu scene está teniendo dificultades para seguir el ritmo del frame rate. Eso podría hacer que el movimiento parezca irregular, ya que no todos los frames tienen la misma duración, pero cada uno mueve el entity la misma cantidad.

Puedes compensar este tiempo 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 puntos mediante system

Si quieres que un entity se mueva suavemente entre dos puntos, usa el lerp (interpolación lineal). Este algoritmo es muy conocido en el desarrollo de juegos, 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 vectores 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 componente personalizado 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 lineal). Este algoritmo es muy similar a un lerp, pero maneja rotaciones de quaternion.

El slerp() function toma tres parámetros:

  • El quaternion ángulo para la rotación de origen

  • El quaternion ángulo 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 rotación en euler grados (de 0 a 360) usando Quaternion.fromEulerDegrees().

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



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

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, como el incremento máximo es de dt * 10 grados, la rotación se realizará en un período de un par de 9 segundos.

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 completada la rotación.

Cambiar el scale entre dos tamaños mediante system

Si quieres que un entity cambie de tamaño de forma suave y sin cambiar sus proporciones, usa el lerp (interpolación lineal) del Scalar objeto.

De lo contrario, si quieres cambiar cada eje con distintas proporciones, usa Vector3 para representar el scale de origen y el scale de destino, y luego usa la lerp function del Vector3.

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

  • Un número para el scale de origen

  • Un número para el scale de destino

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

Para implementar este lerp en tu scene, 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 puntos mediante sistema

Al usar 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 de otras formas que te den un ritmo de movimiento diferente.

También podrías usar una función que produzca 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 acelera sobre una curva o 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 mostramos 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 rotación o en scale de la misma manera que se muestra arriba, mapeando una transición lineal a una curva.



Seguir una ruta mediante sistema

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

El ejemplo anterior define una ruta 3D que está compuesta por cuatro vectors 3D. El PathTransportData custom component contiene los mismos datos usados por el custom component en el lerp ejemplo anterior, pero añade un path array, con todos los puntos de nuestra ruta, y un pathTargetIndex campo para llevar el control de qué segmento de la ruta se está usando actualmente.

El system es muy similar al system en el lerp ejemplo, pero cuando se completa una acción lerp, establece los campos target y origin con nuevos valores. Si llegamos al final de la ruta, volvemos al primer valor de la ruta.



Tweens de textura

Para hacer que una texture se deslice suavemente, usa el Tween component con el setTextureMove function.

El tween de textura toma la siguiente información:

  • entity: La entity de la que mover la texture

  • start: Un Vector2 para la posición inicial

  • end: Un Vector2 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:

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

  • easingFunction: Qué función de easing usar. Ver Tweens no lineales. Nota: Este parámetro solo se usa si se proporciona una duration.

Movimiento constante de textura

Para hacer que una texture se deslice constantemente, usa el Tween component con el setTextureMoveContinuous function.

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

  • entity: La entity de la que mover la texture

  • direction: Un Vector2 para el movimiento

  • speed: Cuántas unidades por segundo se moverá la entity

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

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

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

Lee más sobre los tweens de textura en Tweens de textura .

Última actualización