Reproductor de Seqüències

Un únic motor asíncron genèric per a tot flux ordenat de diversos passos — avisos de tutorial, intros de cap, canvis de fase — reproduïts pel mateix servei, declaratiu en lloc de corrutines niades.

Per a què serveix aquest sistema

La majoria de projectes Unity necessiten orquestrar fluxos ordenats de diversos passos: mostrar un avís, esperar, ressaltar alguna cosa, esperar un altre cop, tornar el control. Tant si és una seqüència de tutorial, una introducció de cap o un moment de gameplay guionitzat, el problema de fons és el mateix: executar una llista d'etapes en ordre i esperar que acabi abans de tornar el control a qui ha cridat.

Serenity ho resol una sola vegada amb ISequencePlayerService, un orquestrador asíncron genèric al namespace Serenity.SequencePlayer. No sap res de cinemàtiques, diàlegs ni cap altre domini: només sap reproduir una llista ordenada d'etapes i esperar el resultat, deixant cada decisió de vocabulari al vertical que s'hi recolzi a sobre.

El problema a Unity

Sense un motor compartit, cada flux coreografiat acaba sent la seva pròpia corrutina o màquina d'estats. Un pas de tutorial, una intro de cap i un esdeveniment guionitzat s'implementen de tres maneres diferents, es proven de tres maneres diferents i es depuren de tres maneres diferents. La cancel·lació, la gestió d'errors i el logging es copien i enganxen o s'ometen. Els punts de crida depenen de MonoBehaviours concrets en lloc d'interfícies estables.

El cost real és el manteniment. Un sol canvi de disseny — afegir un pas, reordenar una fase — toca diverses implementacions. Un motor que cableja el seu vocabulari d'etapes ho empitjora: cada nou tipus de flux o força un membre nou en un enum compartit o queda directament descartat.

Com ho aborda Serenity

ISequencePlayerService exposa dues sobrecàrregues de PlayAsync: una que accepta una clau de text i resol la definició en runtime, i una altra que accepta directament una instància d'ISequenceDefinition. Totes dues retornen una Task esperable, així que qui crida pot programar una seqüència, esperar-la i continuar amb la lògica de joc en una sola línia. Cada ISequenceDefinition conté un IReadOnlyList ordenat d'unitats ISequenceStage; les etapes que necessiten una durada explícita implementen ITimedSequenceStage, que afegeix una propietat DurationSeconds.

ISequenceStage ja no porta un enum d'etapes tancat i propietat del motor. El seu membre Kind és una cadena de text plana que el motor no interpreta mai: existeix únicament perquè un vertical construït sobre el motor defineixi el seu propi vocabulari d'etapes i hi ramifiqui. Un sistema de tutorials pot fer servir valors de Kind com «Highlight» o «WaitForInput» sense tocar mai el codi del motor, i el Reproductor de Cinemàtiques — el vertical cinemàtic construït sobre aquest mateix motor — fa el mateix amb els seus noms d'etapa cinemàtics.

Com encaixa a Serenity

El namespace SequencePlayer segueix l'estructura per capes de Serenity. La capa d'Aplicació conté ISequencePlayerService, la interfície de factoria ISequencePlayerServiceFactory, ISequencePlayerSettings i els contractes ISequenceDefinition i ISequenceStage — deliberadament lliures de qualsevol tipus d'etapa específic de domini. La capa d'Infraestructura aporta la implementació Unity; la capa d'Instal·lació ho connecta tot a través de la pipeline d'inicialització de Serenity perquè els consumidors només vegin interfícies.

El Reproductor de Seqüències coopera amb el sistema de Feedback per a efectes de pantalla, amb el Reproductor de música per arrencar o aturar pistes en etapes concretes, amb Game Mode per assenyalar que hi ha una seqüència guionitzada activa i que altres sistemes hi puguin reaccionar, i amb l'Event Dispatcher per publicar senyals de cicle de vida d'etapa que la interfície o l'analítica puguin observar.

Flux de treball pràctic

  1. Defineix la teva seqüència com un ScriptableObject que implementi ISequenceDefinition i registra'n la clau a ISequencePlayerSettings.
  2. Implementa cada etapa com una classe que implementi ISequenceStage o ITimedSequenceStage, donant a Kind un valor de text amb sentit per al teu propi sistema.
  3. Deixa que l'instal·lador registri ISequencePlayerService a través de la pipeline d'inicialització.
  4. Injecta ISequencePlayerService a qualsevol punt de crida que necessiti orquestrar un flux de diversos passos.
  5. Crida PlayAsync amb una clau de text o una instància de definició i espera el resultat: el motor reprodueix les etapes ordenades i torna el control quan acaba l'última.
  6. Fes servir CancellationToken per avortar a mitja seqüència en descarregar una escena o canviar d'estat de joc sense deixar el motor en un estat inconsistent.

Què inclou

  • ISequencePlayerService amb dues sobrecàrregues de PlayAsync — reproduir per clau de text o per instància d'ISequenceDefinition
  • ISequenceDefinition amb un IReadOnlyList ordenat d'unitats ISequenceStage per a l'orquestració en runtime
  • ITimedSequenceStage que estén ISequenceStage amb DurationSeconds per a l'execució d'etapes per temps
  • ISequenceStage.Kind com una cadena plana i agnòstica al motor, perquè els verticals defineixin el seu propi vocabulari d'etapes en lloc d'estendre un enum compartit
  • ISequencePlayerSettings exposant DefinitionIds per al registre des de l'inspector
  • Interfície de factoria ISequencePlayerServiceFactory per a implementacions intercanviables
  • Suport de CancellationToken d'extrem a extrem perquè les seqüències avortin nètament en transicions d'escena o canvis d'estat
  • Una base estable per a verticals de domini — el Reproductor de Cinemàtiques es distribueix com el vertical cinemàtic construït sobre aquest mateix motor

Quan fer-lo servir

  • Fluxos de tutorial que han d'executar una llista ordenada d'avisos, ressaltats i pauses abans de tornar el control.
  • Introduccions de cap, canvis de fase o moments de gameplay guionitzats que necessiten executar-se com una llista ordenada de passos.
  • Jocs on el mateix patró de coreografia de diversos passos es repeteix en contextos diferents i vols un motor, no N corrutines.
  • Bases de codi que necessiten esperar que una seqüència acabi abans de disparar la següent transició d'estat, sense lligar qui crida a un conjunt fix de tipus d'etapa.

Sistemes relacionats

Fes servir Serenity quan vulguis un únic motor d'orquestració asíncrona per a tot flux ordenat del teu projecte, amb un vocabulari d'etapes que continua sent teu en lloc de venir cuit al framework.

Tornar a la pàgina principal