Procedural Animator

Moviment procedural independent del motor que composa contribucions additives de PoseDelta a partir de capes ponderades, accions amb cicle de vida i seqüències d'activació d'un sol tret — en cinc canals declarats — sobre qualsevol rig, prop o element d'UI.

Per a què serveix aquest sistema

L'animació esquelètica i el moviment procedural no són oposats: funcionen millor junts. Un personatge pot reproduir un clip de locomoció i respirar, balancejar-se i estremèixer-se alhora, perquè totes aquestes contribucions són desplaçaments additius superposats al que l'animador hagi creat. La dificultat és fer-ho de manera neta, sense que el codi procedural conegui res sobre transformades de Unity, renderers ni el bucle d'actualització.

El sistema Procedural Animator de Serenity resol això. Defineix un model de composició construït al voltant de PoseDelta, separa la matemàtica d'avaluació de l'aplicació de transformades a través d'IRigApplier, i dirigeix tot el pipeline des d'un perfil de ScriptableObject perquè la configuració visqui en assets, no en codi.

El problema a Unity

La majoria de projectes Unity afegeixen el moviment procedural tard: un MonoBehaviour que rota directament un os de columna per a la respiració, un altre que interpola una transformada de cap per al seguiment d'objectiu, i una corrutina que sacseja la càmera per al retrocés. Cadascun llegeix de les transformades de Unity, hi escriu de tornada i trepitja tots els altres scripts que també les toquen. El resultat són bugs d'ordre d'operacions, conflictes d'animació i un sistema que ningú vol estendre.

Quan una reacció a cop, una capa de respiració i un offset d'apuntat escriuen en els mateixos ossos de manera independent, la posa final depèn de l'ordre d'execució dels scripts i de quin Update ha executat en últim lloc. No hi ha cap pressupost de composició, cap sistema de pesos ni cap manera de previsualitzar el resultat combinat sense entrar en mode de reproducció.

Com ho aborda Serenity

Procedural Animator introdueix dos contractes de participació. IProceduralLayer<TContext> és per a contribucions contínues —respiració, balanceig, seguiment d'objectiu— que avaluen cada fotograma i escriuen en un PoseDelta ponderat pel pes actual de la capa. IProceduralAction<TContext> és per a disparaments únics discrets amb cicle de vida —retrocés, estremiment, ensopegada— que implementen CanStart, OnStart, Tick, IsFinished i OnStop. Tots dos escriuen desplaçaments additius en el mateix acumulador PoseDelta perquè les seves contribucions es composin correctament. A més, cada capa declara quins dels cinc canals escriu realment —Pose, Material, Transform, Activation i UiColor— mitjançant un flag DrivenChannels, de manera que un consumidor aplica només els canals que li interessen en lloc d'endevinar-ho pel tipus concret de la capa.

IRigApplier<TRigDefinition> aïlla la manipulació real de transformades de la matemàtica d'avaluació. El pipeline de composició acumula un PoseDelta, un MaterialDelta, un TransformDelta i un ActivationDelta, i després els lliura a l'applier. TransformRigApplier i UnityMaterialApplier proporcionen les implementacions de Unity, però la lògica de domini mai toca un tipus de Unity. RuleSO connecta condicions amb pesos de capa o disparadors d'acció perquè el comportament es configuri en assets a través de ProceduralAnimatorProfileSO.

Com encaixa a Serenity

Procedural Animator viu al namespace Serenity.ProceduralAnimator i segueix l'estructura per capes de la foundation. La capa de Domini defineix PoseDelta, MaterialDelta, TransformDelta, ActivationDelta, BoneId, MaterialId i IStateReader, tots independents del motor. La capa d'Aplicació declara IProceduralLayer<TContext>, IProceduralAction<TContext> i IRigApplier<TRigDefinition>. La capa d'Infraestructura proporciona les classes base ProceduralLayerSO i ProceduralActionSO, capes i accions concretes, proveïdors de pes, tipus de condició, implementacions d'applier, eines d'editor i ProceduralAnimatorComponent com a driver en temps d'execució.

ProceduralAnimatorProfileSO és l'arrel de composició: agrupa BaseLayers, Rules, MaterialTargets i TransformTargets en un únic asset. Les regles vinculen arbres de Condition a un efecte SetLayerWeight o TriggerAction perquè la posa activa sigui completament data-driven. Les implementacions de WeightProviderSO —ConstantWeightProviderSO i StateKeyWeightProviderSO— permeten que els pesos de capa responguin a valors d'estat en temps d'execució a StateBusComponent. Més enllà del moviment continu de rig, una capa es pot executar en mode de fase ON_ACTIVATE —una seqüència d'un sol tret amb un nombre de repeticions configurat que es reinicia amb cada tret en lloc de seguir el rellotge d'animació compartit— i una ActivationSequenceLayerSO pot encendre i apagar un GameObject com a part d'aquesta seqüència. El sistema s'integra de manera natural amb els sistemes d'input i armes per al retrocés i la vibració, i amb el sistema de seqüències per als canvis d'expressió en cinemàtiques.

Flux de treball pràctic

  1. Afegeix ProceduralAnimatorComponent i UnityRigDefinition al prefab del personatge i enllaça les transformades d'os per nom — o desactiva drivesRig per a un animador sense rig que dirigeixi només materials, transformades o objectius d'activació amb el seu propi rellotge manual, com un element d'UI o un prop.
  2. Crea un asset ProceduralAnimatorProfileSO i assigna capes contínues com PeriodicOscillationLayerSO per a la respiració o PerlinDriftLayerSO per al balanceig.
  3. Crea assets RuleSO que vinculin arbres de Condition amb objectius de pes de capa o disparadors d'acció; fes servir ThresholdCondition o RangeCondition amb valors de state key.
  4. Crea assets ProceduralActionSO per a reaccions discretes —StunRecoilActionSO, FlinchActionSO o StumbleActionSO— i referencia'ls des de regles.
  5. Fes servir StateBusComponent com a magatzem d'estat en temps d'execució; publica valors des del codi de gameplay usant assets UnityStateKey perquè capes i condicions reaccionin automàticament.
  6. Fes servir l'assistent ProceduralAnimatorSetupWindow (Tools ▸ Serenity ▸ Create ▸ Procedural Animator ▸ Setup Minimal Idle) per generar un scaffold amb StateKeys, capes, proveïdors de pes i un perfil d'idle mínim en un sol pas.

Què inclou

  • Contracte IProceduralLayer<TContext> per a contribucions contínues ponderades (respiració, balanceig, seguiment d'objectiu, soroll)
  • Contracte IProceduralAction<TContext> per a disparaments únics discrets amb cicle de vida (retrocés, estremiment, ensopegada)
  • Acumuladors PoseDelta, MaterialDelta, TransformDelta i ActivationDelta compositats abans de tocar cap transformada
  • IRigApplier<TRigDefinition> aïlla l'aplicació d'ossos de la matemàtica d'avaluació per a portabilitat total del motor
  • ProceduralAnimatorProfileSO com a arrel de composició data-driven que agrupa capes, regles i objectius
  • Cada capa declara els seus DrivenChannels (Pose, Material, Transform, Activation, UiColor) perquè el consumidor apliqui només els canals que realment escriu
  • Mode de fase ON_ACTIVATE amb repeticions configurades per a seqüències d'un sol tret redisparables, més una capa de seqüència d'activació que encén i apaga GameObjects
  • Els animadors sense rig corren amb rellotge manual per a elements d'UI i props — el mateix pipeline impulsa els presets d'animació del HUD Builder i el simulador procedural en viu de l'Animation Hub (play/pausa/pas, un control lliscant per state key)
  • RuleSO connecta arbres de Condition amb canvis de pes de capa o disparadors d'acció sense codi
  • Implementacions WeightProviderSO amb mapeig de corba guiat per state key per a pesos de capa reactius
  • StateBusComponent com a bus d'estat en temps d'execució amb suavitzat opcional per a publicació desacoblada d'estat
  • Capes concretes integrades: PeriodicOscillationLayerSO, PerlinDriftLayerSO, HighFrequencyNoiseLayerSO, StateModulatedOffsetLayerSO, RandomImpulseLayerSO, ActivationSequenceLayerSO
  • Accions concretes integrades: StunRecoilActionSO, FlinchActionSO i StumbleActionSO amb atac i recuperació guiats per corba

Quan fer-lo servir

  • Personatges que necessiten respiració, balanceig d'idle o seguiment d'objectiu executant-se al costat de locomoció basada en clips sense conflictes d'animació.
  • Sistemes d'armes que necessiten retrocés, estremiment per cop o reaccions d'ensopegada com a contribucions additives discretes sobre l'animació base.
  • Elements de HUD i altres elements d'UI o props sense rig que necessiten el mateix moviment data-driven per capes que un rig de personatge — polsos, parpelleigs i seqüències d'activació d'un sol tret sense codi extra.
  • Projectes que volen el moviment procedural configurat en assets en lloc de codificat en MonoBehaviours dispersos per les escenes.
  • Bases de codi que necessiten que la mateixa lògica de composició funcioni independentment de com s'apliquin els ossos o transformades al rig de destí.

Sistemes relacionats

Fes servir Serenity quan vulguis moviment procedural que es composi de manera neta amb l'animació esquelètica — o animi elements d'UI i HUD sense ella —, respongui a l'estat en temps d'execució a través de regles data-driven i no toqui cap transformada de Unity fins que el delta complet estigui llest.

Tornar a la pàgina principal