Mover Entidades
Como mover, rotacionar e escalar uma entidade gradualmente ao longo do tempo, com mudanças incrementais.
Para mover, rotacionar ou redimensionar uma entidade na sua cena durante um período de tempo, use o Tween componente. O engine realiza a transformação desejada de forma suave, atualizando em cada frame até que a duração especificada termine. Além disso o Transform valores do componente da entidade afetada são atualizados em tempo real caso seja necessário fazer verificações de proximidade no código da cena.
💡 Tip: No Scene Editor in Creator Hub, você pode mover entidades de forma no-code via Actions, veja Tornar qualquer item inteligente.
O componente Tween possui as seguintes funções:
setMove: Mover entre dois pontossetRotate: Rotacionar entre duas direçõessetScale: Escalonar entre dois tamanhossetMoveContinuous: Mover constantemente na mesma direçãosetRotateContinuous: Rotacionar constantemente na mesma direçãosetTextureMove: Deslocar a textura de um material entre duas posiçõessetTextureMoveContinuous: Deslocar a textura de um material constantemente na mesma direção
Mover entre dois pontos
Para mover uma entidade entre dois pontos, crie um Tween componente com o setMove função.
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
)O tween de movimento recebe as seguintes informações:
entidade: A entidade a ser movidastart: Um Vector3 para a posição inicialend: Um Vector3 para a posição finalduration: Quantos milissegundos leva para se mover entre as duas posições
Estes outros parâmetros opcionais também estão disponíveis:
faceDirection: Se true, a entidade é rotacionada para olhar na direção do movimento.easingFunction: Qual função de easing usar. Veja Tweens não lineares
Rotacionar entre duas direções
Para rotacionar uma entidade entre duas posições, crie um Tween componente com o setRotate função.
O tween de rotação recebe as seguintes informações:
start: Um Quaternion para a rotação inicialend: Um Quaternion para a rotação finalduration: Quantos milissegundos leva para se mover entre as duas posições
Este outro parâmetro opcional também está disponível:
easingFunction: Qual função de easing usar. Veja Tweens não lineares
Rotacionar com um ponto de pivô
Ao rotacionar uma entidade, a rotação é sempre em referência à coordenada central da entidade. Para rotacionar uma entidade usando outro conjunto de coordenadas como ponto de pivô, crie uma segunda entidade (invisível) com o ponto de pivô como sua posição e torne-a pai da entidade que você quer rotacionar.
Ao rotacionar a entidade pai, seus filhos serão todos rotacionados usando a posição do pai como ponto de pivô. Note que o position da entidade filha está em referência ao da entidade pai.
Note que neste exemplo, o sistema está rotacionando o pivotEntity entidade, que é um pai do childEntity entidade engine.CameraEntity
Escalonar entre dois tamanhos
Para alterar a escala de uma entidade entre dois tamanhos, crie um Tween componente com seu modo definido para Tween.Mode.Scale.
O tween de escala recebe as seguintes informações:
start: Um Vector3 para o tamanho inicialend: Um Vector3 para o tamanho finalduration: Quantos milissegundos leva para se mover entre as duas posições
Este outro parâmetro opcional também está disponível:
easingFunction: Qual função de easing usar. Veja Tweens não lineares
Tweens não lineares
Tweens podem seguir diferentes Funções de Easing que afetam a taxa de mudança ao longo do tempo. Uma linear function, significa que a velocidade da mudança é constante do começo ao fim. Existem muitas opções para escolher, que desenham curvas de formatos diferentes dependendo se o começo e/ou fim inicia lento, e o quanto. Um easeinexpo curve começa devagar e termina rápido, aumentando a velocidade exponencialmente, ao contrário de uma easeoutexpo curve que começa rápido e termina devagar.
💡 Tip: Experimente diferentes curvas de movimento. As diferenças são frequentemente sutis, mas subconscientemente interpretamos informações a partir de como as coisas se movem, como peso, fricção ou até personalidade.
O opcional easingFunction parâmetro toma seu valor do EasingFunction enum, que oferece as seguintes opções:
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
Rotação constante
Para fazer uma entidade rotacionar constantemente, use o Tween componente com o setRotateContinuous função.
O tween de rotação contínua recebe as seguintes informações:
entidade: A entidade a ser rotacionadacampo: Um Quaternion para a rotaçãoAltere a velocidade com que uma animação é reproduzida alterando a propriedade: Quantos graus por segundo a entidade irá rotacionar
Este outro parâmetro opcional também está disponível:
duration: Quantos milissegundos sustentar a rotação. Após esse tempo, a rotação irá parar.
Movimento constante
Para fazer uma entidade mover-se constantemente na mesma direção, use o Tween componente com o setMoveContinuous função.
O tween de movimento contínuo recebe as seguintes informações:
entidade: A entidade a ser movidacampo: Um Vector3 para o movimentoAltere a velocidade com que uma animação é reproduzida alterando a propriedade: Quantos metros por segundo a entidade irá se mover
Este outro parâmetro opcional também está disponível:
duration: Quantos milissegundos sustentar o movimento. Após esse tempo, o movimento irá parar.
O tween de movimento contínuo recebe as seguintes informações:
Sequências de Tween
Para fazer uma entidade executar uma série de tweens em sequência, use o TweenSequence componente. Este componente requer dois campos:
sequence: Um array com múltiplas definições de tween, que serão executadas sequencialmente. O array pode estar vazio, caso em que apenas toca o tween atual.loop(opcional): Se não fornecido, a sequência é tocada apenas uma vez. Se o campo estiver presente, o valor deve ser um valor doTweenLoopenum. Valores aceitos são:TL_RESTART: Quando a sequência termina, ela reinicia. Se o último estado não corresponder ao primeiro estado, a entidade salta instantaneamente de um para o outro.TL_YOYO: Quando a sequência termina, ela volta para trás, executando todos os tweens em reverso até alcançar o início novamente. Então começa mais uma vez.
Mover de um lado para o outro
Para fazer uma plataforma mover-se constantemente de um lado para o outro entre duas posições, deixe o sequence array vazio, e defina loop para TweenLoop.TL_YOYO
A entidade irá mover-se de um lado para o outro entre o ponto inicial e o ponto final, com a mesma duração e a mesma função de easing em ambas as direções.
Seguir um caminho
Para fazer uma entidade seguir um caminho mais complexo com múltiplos pontos, forneça uma lista de definições de tween no sequence de um TweenSequence component.
Note que ao definir um tween dentro de um TweenSequence, você precisa usar o formato mais verboso de Tween.Mode.Move, ou Tween.Mode.Rotate, ou Tween.Mode.Scale para definir o tween. Neste formato mais verboso, você precisa especificar:
duration: Quantos milissegundos leva para se mover entre as duas posiçõeseasingFunction: Qual função de easing usar. Veja Tweens não lineares. Neste formato o valor é obrigatório.mode: O modo do tween, que pode serTween.Mode.Move,Tween.Mode.Rotate, ouTween.Mode.Scale.
E dentro do campo mode você precisa especificar:
start: O valor inicial do tweenend: O valor final do tween
Ao terminar um tween
Use tweenSystem.tweenCompleted para detectar quando um tween terminou. Isso pode ser útil para executar ações quando um tween termina, por exemplo para abrir a porta de um elevador.
Tweens simultâneos
Uma entidade só pode ter um Tween componente, e cada componente tween só pode executar uma transformação por vez. Por exemplo, você não pode fazer uma entidade mover-se lateralmente e também rotacionar ao mesmo tempo. Como solução alternativa, você pode usar entidades parentadas. Por exemplo, você pode ter uma entidade pai invisível que se move lateralmente, com um filho visível que rotaciona.
No trecho a seguir, uma entidade pai rotaciona enquanto um filho aumenta de escala.
Pausar um tween
Para pausar um tween, altere a propriedade playing para false. Para retomá-lo, altere-a de volta para true.
Para encerrar um tween que não precisa ser continuado, exclua o Tween componente da entidade. Se a entidade também estava usando um TweenSequence componente, exclua esse também.
Tweens baseados em um sistema
Ao invés de usar o componente Tween e deixar o engine lidar com a transformação, você pode preferir fazer essa transição de forma incremental, frame a frame, via um sistema na sua cena. Movendo a entidade uma pequena quantidade cada vez que a função é executada.
Por um lado, isso lhe dá mais controle para recalcular movimentos a cada frame. Por outro lado, o código é mais complicado, e jogadores com máquinas menos potentes podem experimentar o tween como com lag, percebendo cada incremento.
Mover via system
A maneira mais fácil de mover uma entidade é modificar gradualmente o position valor armazenado no Transform component.
Neste exemplo estamos movendo uma entidade em 0.1 metros por tick do loop do jogo.
que descreva um vetor relativo à entidade e sua rotação (por exemplo, retorna um vetor que aponta para frente e mede 1 metro de comprimento. Neste exemplo estamos então reduzindo esse vetor para 1/10 de seu comprimento com Vector3.scale(). Se nossa cena tem 30 frames por segundo, a entidade está se movendo a 3 metros por segundo de velocidade.

Rotacionar via system
A maneira mais fácil de rotacionar uma entidade é alterar gradualmente os valores no componente Transform incrementalmente, e executar isso como parte da função de um sistema.
Note que para combinar a rotação atual com cada incremento, estamos usando Quaternion.multiply. Em matemática de quaternions, você combina duas rotações multiplicando-as, NÃO adicionando-as. A rotação resultante de multiplicar um quaternion por outro será a rotação final equivalente após primeiro realizar uma rotação e depois a outra.
Neste exemplo, estamos rotacionando a entidade em 1 grau na direção para cima a cada tick do loop do jogo.
💡 Tip: Para fazer uma entidade sempre rotacionar para olhar para o jogador, você pode adicionar um Billboard componente.

Rotacionar via system sobre um ponto de pivô
Ao rotacionar uma entidade, a rotação é sempre em referência à coordenada central da entidade. Para rotacionar uma entidade usando outro conjunto de coordenadas como ponto de pivô, crie uma segunda entidade (invisível) com o ponto de pivô como sua posição e torne-a pai da entidade que você quer rotacionar.
Ao rotacionar a entidade pai, seus filhos serão todos rotacionados usando a posição do pai como ponto de pivô. Note que o position da entidade filha está em referência ao da entidade pai.
Note que neste exemplo, o sistema está rotacionando o pivotEntity entidade, que é um pai do childEntity entidade engine.CameraEntity

Ajustar movimento para tempo de atraso
Suponha que o jogador que visita sua cena esteja tendo dificuldades em acompanhar o ritmo da taxa de frames. Isso poderia resultar no movimento parecendo irregular, pois nem todos os frames são igualmente espaçados, mas cada um move a entidade na mesma quantidade.
Você pode compensar esse tempo desigual usando o O exemplo acima executa um raycast recorrente a cada 0,1 segundos. Ele usa um componente timer e a parâmetro para ajustar a escala do movimento.
O exemplo acima mantém o movimento aproximadamente na mesma velocidade que o exemplo de movimento acima, mesmo se a taxa de frames cair. Quando executado a 30 frames por segundo, o valor de O exemplo acima executa um raycast recorrente a cada 0,1 segundos. Ele usa um componente timer e a é 1/30.
Você também pode suavizar rotações da mesma forma multiplicando a quantidade de rotação por O exemplo acima executa um raycast recorrente a cada 0,1 segundos. Ele usa um componente timer e a.
Mover entre dois pontos via system
Se você quiser que uma entidade se mova suavemente entre dois pontos, use o lerp (interpolação linear) algoritmo. Este algoritmo é muito conhecido no desenvolvimento de jogos, pois é realmente útil.
O lerp() função recebe três parâmetros:
O vetor para a posição de origem
O vetor para a posição alvo
A quantidade, um valor de 0 a 1 que representa qual fração da translação executar.
O algoritmo de interpolação linear encontra um ponto intermediário no caminho entre ambos os vetores que corresponde à quantidade fornecida.
Por exemplo, se o vetor de origem é (0, 0, 0) e o vetor alvo é (10, 0, 10):
Usar uma quantidade de 0 retornaria (0, 0, 0)
Usar uma quantidade de 0.3 retornaria (3, 0, 3)
Usar uma quantidade de 1 retornaria (10, 0, 10)
Para implementar isso lerp() na sua cena, recomendamos criar um componente personalizado para armazenar as informações necessárias. Você também precisa definir um sistema que implemente o movimento gradual a cada frame.

Rotacionar entre dois ângulos via system
Para rotacionar suavemente entre dois ângulos, use o slerp (esférica interpolação linear) algoritmo. Este algoritmo é muito similar a um lerp, mas ele lida com rotações em quaternion.
O slerp() função recebe três parâmetros:
O quaternion ângulo para a rotação de origem
O quaternion ângulo para a rotação alvo
A quantidade, um valor de 0 a 1 que representa qual fração da translação executar.
💡 Tip: Você pode passar valores de rotação em euler graus (de 0 a 360) usando Quaternion.fromEulerDegrees().
Para implementar isso na sua cena, recomendamos armazenar os dados que entram na Slerp() função em um componente personalizado. Você também precisa definir um sistema que implemente a rotação gradual a cada frame.
📔 Nota: Você poderia em vez disso representar a rotação com ângulos euler como espera um valores e usar uma Lerp() função, mas isso implicaria uma conversão de espera um para normalHit em cada frame. Valores de rotação são internamente armazenados como quaternions no Transform componente, então é mais eficiente para a cena trabalhar com quaternions.

Uma abordagem mais simples, porém menos eficiente, para isso aproveita a Quaternion.rotateTowards função, e evita usar quaisquer componentes personalizados.
No exemplo acima Quaternion.rotateTowards leva três argumentos: a rotação inicial, a rotação final desejada e o incremento máximo por frame. Neste caso, como o incremento máximo é de dt * 10 graus, a rotação será realizada durante um período de alguns 9 segundos.
Note que o sistema também verifica se a rotação está completa e, se assim for, remove o sistema do engine. Caso contrário, o sistema continuaria fazendo cálculos a cada frame, mesmo depois que a rotação estivesse completa.
Mudar escala entre dois tamanhos via system
Se você quiser que uma entidade mude de tamanho suavemente e sem alterar suas proporções, use o lerp (interpolação linear) algoritmo do Scalar objeto.
Caso contrário, se você quiser alterar o eixo em diferentes proporções, use espera um para representar a escala de origem e a escala alvo, e então use a lerp função do espera um.
O lerp() função do Scalar objeto recebe três parâmetros:
Um número para a escala de origem
Um número para a escala alvo
A quantidade, um valor de 0 a 1 que representa qual fração da escala executar.
Para implementar esse lerp na sua cena, recomendamos criar um componente personalizado para armazenar as informações necessárias. Você também precisa definir um sistema que implemente a escala gradual a cada frame.

Mover em velocidades irregulares entre dois pontos via system
Enquanto usa o método lerp, você pode tornar a velocidade do movimento não linear. No exemplo anterior incrementamos a quantidade do lerp por um determinado valor a cada frame, mas também poderíamos usar uma função matemática para aumentar o número exponencialmente ou em outras medidas que lhe deem um ritmo de movimento diferente.
Você também poderia usar uma função que dê resultados recorrentes, como uma função seno, para descrever um movimento que vai e volta.
Frequentemente essas transições não lineares podem dar muita vida a uma cena. Um movimento que acelera seguindo uma curva ou desacelera gradualmente pode dizer muito sobre a natureza de um objeto ou personagem. Você pode até tirar proveito de funções matemáticas que adicionem efeitos de quique.
O exemplo acima é igual ao exemplo de lerp linear que mostramos antes, mas o fraction campo mapeado para um valor não linear a cada tick. Esse valor não linear é usado para calcular a lerp função, resultando em um movimento que segue uma curva exponencial.
Você também pode mapear uma transição em rotação ou em escala da mesma forma mostrada acima, mapeando uma transição linear para uma curva.

Seguir um caminho via system
Você pode fazer uma entidade percorrer um array de vetores, realizando um movimento por lerp entre cada um para seguir um caminho mais complexo.
O exemplo acima define um caminho 3D composto por quatro vetores 3D. O PathTransportData componente personalizado mantém os mesmos dados usados pelo componente personalizado no lerp exemplo acima, mas adiciona um path array, com todos os pontos do nosso caminho, e um pathTargetIndex campo para acompanhar qual segmento do caminho está sendo usado atualmente.
O sistema é muito semelhante ao sistema no lerp exemplo, mas quando uma ação de lerp é concluída, ele define os position. O e origin campos para novos valores. Se atingirmos o fim do caminho, retornamos ao primeiro valor do caminho.

Tween de textura
Para fazer uma textura deslizar suavemente, use o Tween componente com o setTextureMove função.
O tween de textura recebe as seguintes informações:
entidade: A entidade cuja textura será movimentadastart: Um Vector2 para a posição inicialend: Um Vector2 para a posição finalduration: Quantos milissegundos leva para se mover entre as duas posições
Este outro parâmetro opcional também está disponível:
movementType: (opcional), define se o movimento será no campo offset ou tiling. Por padrão usa offset.easingFunction: Qual função de easing usar. Veja Tweens não lineares. Observação: Este parâmetro é usado apenas se uma duração for fornecida.
Movimento constante de textura
Para fazer uma textura deslizar constantemente, use o Tween componente com o setTextureMoveContinuous função.
O tween contínuo de textura recebe as seguintes informações:
entidade: A entidade cuja textura será movimentadacampo: Um Vector2 para o movimentoAltere a velocidade com que uma animação é reproduzida alterando a propriedade: Quantas unidades por segundo a entidade irá mover
Este outro parâmetro opcional também está disponível:
movementType: define se o movimento será no campo offset ou tiling. Por padrão usa offset.duration: Quantos milissegundos sustentar o movimento. Após esse tempo, o movimento irá parar.
Leia mais sobre tweens de textura em Texture Tweens seção.
Atualizado