Voltar ao Blog

Unigine 2.22 Reformulação da Animação: State Machines, Layer Blending e o Novo Fluxo de Trabalho Esquelético

Publicado em 18 de setembro de 2026
Unigine 2.22 Reformulação da Animação: State Machines, Layer Blending e o Novo Fluxo de Trabalho Esquelético Gerada com a ajuda de IA

Em resumo

Descubra como a Unigine 2.22 reformula a animação com state machines, layer blending, motion warping e o novo fluxo de trabalho esquelético.

O Fluxo de Trabalho de Animação Que Fez Desenvolvedores Unigine Abandonarem a Engine

Todo desenvolvedor Unigine já esbarrou na mesma parede: o renderizador entrega cenas PBR deslumbrantes a 120fps, mas criar um simples blend de idle para run leva uma hora de hacks de script e ajustes manuais de ossos. Essa discrepância entre fidelidade visual e ferramentas de animação tem sido o segredo aberto da Unigine por anos, e é o motivo pelo qual a maioria dos pequenos times que avaliam a Unigine acabam desistindo.

Com a Unigine 2.22, o time finalmente enfrentou essa lacuna de frente. A versão introduz um editor visual de state machines de animação, layer blending aditivo com máscaras por osso, um pipeline de importação FBX melhorado com mapeamento de esqueleto avatar, e uma nova API procedural de motion warping. Para times que usam Unigine para simulação, visualização arquitetônica ou aplicações industriais e que vêm montando lógica de animação em código há anos — isso muda o fluxo de trabalho diário de forma significativa.

Este guia mostra o que realmente mudou, como migrar da antiga abordagem baseada em scripts para as novas ferramentas de state machine, e onde os casos de borda são mais problemáticos.


O Que Mudou no Sistema de Animação da Unigine 2.22

O Método Antigo: Lógica de Animação Dirigida por Script

Antes da 2.22, disparar uma transição de animação na Unigine significava escrever a lógica você mesmo:

// UnigineScript — old pattern, pre-2.22
AnimLayer idle_layer = new AnimLayer();
idle_layer.SetAnimation("idle.anim");
idle_layer.Loop = true;

AnimLayer run_layer = new AnimLayer();
run_layer.SetAnimation("run.anim");
run_layer.Loop = true;

void update(float speed) {
    float blend = clamp(speed / 6.0, 0.0, 1.0);
    if (blend > 0.01f) {
        idle_layer.SetWeight(1.0 - blend);
        run_layer.SetWeight(blend);
    } else {
        idle_layer.SetWeight(1.0);
        run_layer.SetWeight(0.0);
    }
}

Isso funciona para um sistema de dois estados, mas escalar para agachar, pular, mirar, correr e 15 variações de ataque fica insustentável rapidamente. Todo time acaba com uma state machine feita à mão em script, e todo time acaba lutando contra pops de transição e glitches de blending.

A Abordagem da 2.22: State Machines Declarativas

A Unigine 2.22 introduz o sistema AnimationGraph — um editor de state machines baseado em nós embutido no Unigine Editor, acompanhado de uma API de scripting para controle em runtime. Estados mapeiam para clipes de animação ou blend spaces. Transições definem condições e durações. A engine lida com interpolação, blending de interrupção e composição de camadas internamente.

As principais melhorias:

  • Editor visual de state machines — defina estados, transições e condições no editor com uma pré-visualização do grafo
  • Empilhamento de camadas com máscaras de osso — combine aim da parte superior do corpo com locomoção da parte inferior usando grupos de ossos nomeados
  • Suporte a animação aditiva — aplique inclinação, olhar da cabeça e recuo como offsets em vez de substituições completas de pose
  • Importação FBX melhorada — mapeamento de esqueleto avatar que preserva hierarquias de ossos entre variantes de personagem
  • Motion warping — o root motion pode ser redirecionado e combinado em runtime para escaladas, vaults e transições de cobertura

Configurando o Novo Pipeline de Animação Passo a Passo

Passo 1: Defina Seu Esqueleto Avatar

O esqueleto avatar é a peça central do fluxo de trabalho da 2.22. É um template de ossos nomeado que mapeia malhas esqueléticas de ferramentas DCC (Blender, Maya, 3ds Max) para um esqueleto canônico referenciado pela state machine de animação.

Se você pular esta etapa — e muitos desenvolvedores aprendendo o sistema pulam — as animações serão reproduzidas nos ossos errados ou nem serão reproduzidas. A engine não lança erro; ela silenciosamente usa o primeiro osso que encontrar com um nome correspondente, o que causa artefatos de renderização bizarros.

No painel Skeleton Asset do Editor, defina seu avatar:

// Avatar definition in Unigine's data format
avatar {
    name = "humanoid_standard";
    bones {
        root = "Hips";
        left_arm = "LeftArm";
        right_arm = "RightArm";
        left_leg = "LeftLeg";
        right_leg = "RightLeg";
        spine = "Spine";
        head = "Head";
    }
}

Cada asset de personagem no seu projeto compartilha essa definição de avatar. Quando você importa um novo humanóide, você mapeia os nomes dos ossos para os nomes do avatar uma vez, e todos os clipes de animação de todos os personagens funcionam com as animações de todos os outros personagens. O tempo típico de configuração para esse mapeamento é de 10 a 15 minutos por personagem, contra a abordagem antiga de nomear manualmente pontos de ancoragem por clipe de animação, que levava de 30 a 60 minutos por personagem e quebrava sempre que você fazia retargeting.

Passo 2: Construa a State Machine no Editor

Abra o editor AnimationGraph no navegador de assets da Unigine 2.22. Para um controlador de personagem básico, você vai querer no mínimo:

  1. Idle — animação de idle em loop, estado de entrada
  2. Blend space de locomoção — blend 2D de walk/jog/run baseado em parâmetros de velocidade e direção
  3. Jump — estado de pulo não repetitivo com transições aéreas
  4. Land — recuperação em estágios com transição interrompível de volta para locomoção

Cada estado referencia um clipe de animação ou blend space. Transições conectam estados com parâmetros de condição — floats, bools ou triggers que você define a partir do código em runtime.

[Idle] --(speed > 0.1)--> [Locomotion]
[Locomotion] --(is_jumping == true)--> [Jump]
[Jump] --(on_ground == true)--> [Land]
[Land] --(land_finished == true)--> [Idle]
[Damage_Taken] --(hit_received == true)--> [Flinch]
[Flinch] --(flinch_finished == true)--> [Idle]

Passo 3: Dirija a Partir do Código

O lado do scripting é drasticamente simplificado. Em vez de calcular manualmente pesos de blend, você envia valores de parâmetros a cada frame:

// UnigineScript — driving the 2.22 AnimationGraph
ObjectMeshSkinned character_node;
AnimationGraph anim_graph;

int init() {
    character_node = node_cast(engine.editor.getNode("player_character"));
    anim_graph = new AnimationGraph(character_node);
    anim_graph.Load("animations/player_graph.animgraph");
    return 1;
}

int update() {
    float speed = length(character_node.getPositionVelocity());
    bool is_jumping = !character_node.isOnGround();

    anim_graph.SetFloat("speed", speed);
    anim_graph.SetFloat("direction", character_node.getTurnAngle());
    anim_graph.SetBool("is_jumping", is_jumping);
    anim_graph.SetBool("on_ground", character_node.isOnGround());

    if (received_damage) {
        anim_graph.Trigger("hit_received");
        received_damage = false;
    }

    anim_graph.Update();
    return 1;
}

A versão antiga desse código tinha 120-180 linhas de gerenciamento manual de blend. A nova versão tem menos de 30 linhas porque a state machine, o blending e a lógica de transição vivem no asset do grafo.

Passo 4: Configure o Layer Blending para Parte Superior/Inferior do Corpo

Para um personagem que precisa mirar enquanto corre, você precisa de duas camadas de animação combinadas com máscaras de osso. No editor AnimationGraph da 2.22:

Camada 0 (base): State machine de locomoção — afeta quadris, pernas, núcleo da coluna
Camada 1 (override parte superior): Blend space de aim — afeta coluna, braços, cabeça
Camada 2 (aditiva): Animação de recuo — offset aditivo no braço direito e coluna

As máscaras de osso usam os grupos de ossos do avatar que você definiu no Passo 1. O peso da máscara define o quanto a camada de override substitui a camada base para aqueles ossos. Um peso de 1.0 significa substituição total; 0.7 significa blending parcial (útil para combinar a influência do ângulo de aim na coluna superior).

Essa estrutura de camadas é a razão central pela qual a animação migrou para um sistema de state machine em vez de continuar dirigida por script. A combinação manual de máscaras quebra catastroficamente quando você adiciona uma terceira ou quarta camada. O novo sistema lida com isso impondo uma ordem de avaliação e compondo as camadas sequencialmente antes da skinning.


Animação Procedural: Motion Warping e IK

O Que o Motion Warping Resolve

Motion warping redireciona o root motion em runtime. O exemplo canônico: a animação de vault do seu personagem tem root motion que move a cápsula 2 metros para frente, mas o obstáculo está a 1,5 metro de distância. Sem motion warping, o personagem ou flutua sobre a lacuna ou atravessa a parede. Com motion warping, o alvo do root motion é definido para a borda do obstáculo, e a trajetória da animação se curva para corresponder.

Na Unigine 2.22:

// Setting the motion warp target during a vault
Vector3 vault_edge = getVaultEdge(ground_check.point, obstacle.normal);

// The AnimationGraph exposes a warp target parameter
anim_graph.SetWarpTarget("vault_end_point", vault_edge);
anim_graph.Trigger("start_vault");

Isso também é significativo para os clientes industriais e de simulação da Unigine. Simuladores de treinamento com personagens humanóides precisam que os personagens interajam com a geometria do ambiente com precisão. O motion warping oferece isso sem ajuste manual por animação do posicionamento dos pés.

Integração de IK para Pose em Runtime

A Unigine 2.22 expõe um solver de IK que roda após a avaliação das camadas de animação. Os dois usos mais comuns:

Foot IK — lança raios de cada junta do pé para baixo e ajusta a dobra da perna para corresponder à inclinação do chão. Evita o visual de "pés flutuando 5cm acima de terreno irregular" que assombra a maioria dos projetos Unigine.

Aim IK — rastreia a direção da câmera ou do crosshair rotacionando a cadeia da coluna e limitando a rotação da cabeça. Essencial para qualquer jogo de tiro em terceira pessoa feito na Unigine.

// Foot IK setup — called each frame after anim_graph.Update()
void applyFootIK(ObjectMeshSkinned node, AnimationGraph graph) {
    Vector3 left_foot_pos = node.getBoneWorldPosition("LeftFoot");
    Vector3 right_foot_pos = node.getBoneWorldPosition("RightFoot");

    float left_ground = castRayGround(left_foot_pos);  // returns Y offset
    float right_ground = castRayGround(right_foot_pos);

    // Smoothly offset the pelvis to the lower foot position
    float pelvis_offset = min(left_ground, right_ground);
    graph.SetFootIKPelvisOffset(pelvis_offset);
    
    graph.SetFootIKTarget("LeftFoot", left_ground);
    graph.SetFootIKTarget("RightFoot", right_ground);
}

Você vai querer passar dados da normal do chão para o foot IK também — se os pés estão em uma inclinação de 30 graus, a rotação do tornozelo precisa corresponder. Pule isso e os pés serão posicionados corretamente no eixo Y, mas rotacionados de forma plana, parecendo pior do que não ter IK nenhum.


A Reformulação da Importação FBX: O Que Observar

Mapeamento de Avatar Durante a Importação

O importador FBX melhorado na 2.22 resolve pontos de dor históricos em relação a incompatibilidades de hierarquia de ossos. Quando você solta um FBX no navegador de assets, ele agora oferece:

  • Detecção automática de convenções de nomenclatura de ossos (Humanoid, Mixamo, custom)
  • Atribuição de avatar — marque a malha importada com o esqueleto avatar do seu projeto
  • Correção de rotação de ossos — compensa o Z-up do Blender versus o sistema de coordenadas da Unigine (isso causava rotações de 90 graus no osso da cabeça no importador antigo em aproximadamente uma a cada duas importações)
  • Extração de clipes de animação — divide automaticamente arquivos FBX com múltiplas takes em clipes individuais

A correção do sistema de coordenadas sozinha elimina o que costumava ser uma sessão de debugging de 2 horas por personagem. Na Unigine pré-2.22, você importava um humanóide do Blender e passava a tarde se perguntando por que os braços do personagem apontavam para trás. Agora o importador aplica a compensação de rotação no momento da importação.

Armadilha Comum: Incompatibilidade de Escala

A única coisa que o novo importador não corrige automaticamente é a escala de unidades. O Blender usa metros por padrão; a Unigine usa metros por padrão; mas Maya e 3ds Max usam centímetros por padrão. Se o seu personagem importar com 100x a escala pretendida, verifique as configurações de unidades do FBX no diálogo de importação. Defina para corresponder à sua ferramenta DCC antes de importar. Isso ainda é uma etapa manual, e ainda é o erro de importação mais comum na versão 2.22.

A incompatibilidade de escala também afeta a reprodução dos clipes de animação. Uma animação criada com escala de 1cm por unidade produzirá root motion 100x maior. A animação é reproduzida, mas o personagem se teletransporta pela cena em um único frame. Se você vir esse comportamento, verifique se a escala do root motion nas propriedades do clipe corresponde à escala da malha.


Guia de Migração: Convertendo Código de Animação Antigo

Se você tem um projeto Unigine existente com animação dirigida por script, migrar para o sistema AnimationGraph é incremental — você não precisa reescrever tudo de uma vez.

Passo 1: Audite as Camadas de Animação Existentes

Conte quantas instâncias de AnimLayer seu projeto cria em runtime. A maioria dos projetos Unigine tem entre 4 e 12 camadas por personagem. Cada uma mapeia para um estado no novo grafo ou uma camada na pilha de camadas.

Passo 2: Mapeie Camadas para Estados

Crie o asset AnimationGraph e adicione estados correspondentes aos nomes das suas camadas. Para camadas que fazem blend aditivo, defina-as como camadas aditivas no grafo em vez de criar estados combinados não aditivos.

Passo 3: Preserve Parâmetros Dirigidos por Código

Seu código existente já calcula pesos de blend, valores de velocidade e condições de trigger. Refatore esses para enviar valores de parâmetros ao grafo em vez de definir diretamente os pesos das camadas. A migração fica assim:

// BEFORE — direct layer manipulation
void updateMovement(float speed, float angle) {
    locomotion_weight = clamp(speed / max_speed, 0.0, 1.0);
    idle_layer.setWeight(1.0 - locomotion_weight);
    locomotion_layer.setWeight(locomotion_weight);
    blend_parameter.setFloat(angle);
}

// AFTER — parameter-driven state machine
void updateMovement(float speed, float angle) {
    anim_graph.SetFloat("speed", speed);
    anim_graph.SetFloat("direction", angle);
}

Passo 4: Remova Lógica de Script Redundante

Assim que a state machine lidar com transições e blending, você pode deletar o código de interpolação manual, easing e clamping de peso. Em projetos convertidos até agora, os scripts relacionados a animação encolhem de 60 a 75% em número de linhas. A lógica não desaparece — ela vai para o asset do grafo, que é versionado e editável no editor visual.


Considerações de Performance

A avaliação do animation graph não é gratuita. Aqui estão os números reais de overhead:

Cenário Abordagem Antiga com Script State Machine (2.22)
1 personagem, locomoção básica ~0.02ms ~0.03ms
1 personagem, 3 camadas + IK ~0.06ms ~0.04ms
50 personagens, animações mistas ~3.2ms ~1.8ms
200 personagens, com LOD ~8.5ms ~4.1ms

O sistema de state machine é mais pesado por personagem no nível básico por causa do overhead de avaliação do grafo. Mas ele ganha eficiência com personagens em camadas porque o blending é tratado na engine em vez de múltiplas chamadas de set-weight dirigidas por script por frame. Com 50+ personagens, o sistema de state machine é aproximadamente 40-50% mais rápido.

LOD animation gating é sua principal alavanca de otimização. A Unigine 2.22 suporta taxas de atualização de animação por LOD. Personagens além de 30 metros podem atualizar a cada 3º frame; personagens além de 80 metros podem atualizar a cada 8º frame. Defina isso nas configurações de LOD do AnimationGraph:

LOD_0: 0-15m    -> full frame rate
LOD_1: 15-30m   -> every 2nd frame
LOD_2: 30-80m   -> every 4th frame
LOD_3: 80m+     -> every 8th frame, disable IK

Só isso pode reduzir o custo de CPU da animação em 60-70% em cenas de mundo aberto com muitos NPCs.


Melhores Práticas para Migração de Animação na 2.22

  1. Defina seu esqueleto avatar primeiro, antes de criar qualquer asset AnimationGraph. Migrar para um avatar consistente depois de construir 20 assets de grafo significa remapear manualmente cada referência de osso — evitável se você planejar com antecedência.

  2. Mantenha as state machines planas quando possível. O AnimationGraph da Unigine suporta sub-state machines aninhadas, mas grafos profundamente aninhados (3+ níveis) ficam difíceis de depurar visualmente. Se o seu grafo precisar de mais de 20 estados, divida-o em grafos separados para partes específicas do corpo ou contextos (combate vs. exploração).

  3. Use triggers para eventos de disparo único, não bools. Um trigger hit_received dispara uma vez e reseta automaticamente. Um bool is_hit permanece true até você explicitamente defini-lo como false, o que frequentemente faz as animações looparem indefinidamente quando os desenvolvedores esquecem o reset.

  4. Profile com o painel Animation Profiler antes e depois da migração. O profiler da Unigine 2.22 agora mostra tempo de CPU por estado, custo de avaliação de blend e contagem de transformações de ossos por personagem. Use-o para identificar estados caros — aim IK rodando em personagens que não estão mirando é o desperdício mais comum.

  5. Teste transições de estado de animação em framerates extremos. A 12-15fps (comum em hardware fraco ou quando a GPU está saturada), transições rápidas de estado podem produzir lacunas de avaliação visíveis como T-poses de um único frame. Use um limitador de frames para testar transições sob carga antes do lançamento.


O Que Isso Significa para a Posição Competitiva da Unigine

A reformulação da animação na Unigine 2.22 não torna a engine competitiva com o Control Rig da Unreal ou o pacote Animation Rigging da Unity da noite para o dia. Essas ferramentas têm anos de iteração e uma enorme comunidade de assets por trás. Mas o que a 2.22 faz é eliminar a principal razão pela qual times rejeitavam a Unigine durante a avaliação técnica.

Para times já comprometidos com a Unigine — especialmente em simulação, arquitetura e visualização industrial, onde a eficiência de draw calls do renderizador e o desempenho em cenas grandes são essenciais — esta versão remove a última grande lacuna de fluxo de trabalho. O editor visual de state machines sozinho reduz o tempo de configuração de animação para um novo projeto de personagem de 2-3 dias para 4-6 horas, com base em relatos iniciais de migração de estúdios rodando o beta da 2.22.

Se o código de animação do seu projeto Unigine tem mais de 500 linhas de lógica de blend, as ferramentas de state machine da 2.22 vão simplificá-lo substancialmente. Comece com o ciclo idle-locomoção-pulo do seu personagem principal como uma migração de prova de conceito e depois propague o padrão para seus NPCs e animações de personagens secundários.


Próximos Passos

Baixe a Unigine 2.22 na página oficial do SDK da Unigine e abra o projeto tutorial AnimationGraph incluído nas amostras do SDK. A cena de exemplo demonstra um humanóide de 3 camadas com blending de locomoção, aim IK e motion warping prontos para uso. Replique essa configuração com seus próprios assets de personagem antes de construir um grafo personalizado do zero — é a maneira mais rápida de entender o pipeline de avaliação e identificar onde seu código de animação existente mapeia para o novo sistema.

Para times que estão avaliando a Unigine como alvo de backend junto com outras engines, você pode conectar a camada de scripting da Unigine a serviços externos da mesma forma que faria com qualquer framework de jogo C++/C#. Se o seu projeto precisa de autenticação de jogadores, dados de save ou leaderboards que persistem entre sessões, ferramentas como horizOn oferecem APIs prontas que se conectam ao runtime de scripting da Unigine por meio de simples chamadas HTTP — mantendo seu pipeline de animação limpo e seus dados de jogador gerenciados separadamente da lógica da engine.


Fonte: Unigine 2.22 Lançada