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
- Defineix la teva seqüència com un ScriptableObject que implementi ISequenceDefinition i registra'n la clau a ISequencePlayerSettings.
- 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.
- Deixa que l'instal·lador registri ISequencePlayerService a través de la pipeline d'inicialització.
- Injecta ISequencePlayerService a qualsevol punt de crida que necessiti orquestrar un flux de diversos passos.
- 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.
- 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.
English
Español
Català