Completando questo passaggio del tutorial Puzzle delle luci con tag, imparerai a rilevare quando il giocatore risolve il puzzle, in modo da poter generare un oggetto e impedire ulteriori interazioni con il puzzle
Rilevamento di un puzzle risolto
Questa sezione mostra come rilevare quando il giocatore risolve il puzzle trovando la giusta combinazione di luci. Quando il puzzle è risolto, il dispositivo Generatore oggetti deve essere abilitato in modo che possa generare il suo oggetto.
Per rilevare quando il giocatore risolve il puzzle, attieniti ai passaggi seguenti:
- Aggiungi un campo modificabile
item_spawner_devicechiamatoItemSpawneralla classetagged_lights_puzzle, per rappresentare il dispositivo Generatore oggetti.@editable ItemSpawner:item_spawner_device = item_spawner_device{} - Quindi, definisci lo stato in cui devono trovarsi le luci per risolvere il puzzle. Poiché la rappresentazione dello stato delle luci è un array
logic, anche lo stato risolto delle luci dovrebbe essere un arraylogicper poter confrontare facilmente i due. Crea un campo arraylogicmodificabile, denominatoSolvedLightsState, nella classetagged_lights_puzzle. In questo esempio, il giocatore deve accendere tutte le luci per risolvere il puzzle, quindi inizializzare ogni elemento con il valoretrueper rappresentare la luce accesa.@editable SolvedLightsState : []logic = array{true, true, true, true} - Salva il file in Visual Studio Code.
- Nella barra degli strumenti UEFN, fai clic su Compila gli script di Verse per aggiornare il tuo dispositivo di Verse nel livello.
- In Outliner, seleziona tagged_lights_puzzle per aprire il relativo pannello Dettagli.
- Nel pannello Dettagli, imposta la proprietà Generatore oggetti sul dispositivo Generatore oggetti presente nel livello.
- Successivamente, sviluppa il codice che verifica se il
LightsStatecorrente corrisponde alSolvedLightsState. Aggiungi un nuovo metodo denominatoIsPuzzleSolved()alla classetagged_lights_puzzle. Questo metodo deve riuscire se il puzzle è risolto e fallire in caso contrario, per comunicare al chiamante il risultato della verifica. Ciò significa che il metodo deve essere contrassegnato come in grado di fallire, utilizzando lo specificatoredecides. Poiché il metodo presenta lo specificatoredecides, deve avere anche lo specificatoretransacts, il che significa che è possibile eseguire il rollback delle azioni eseguite da questo metodo (come se non fossero mai state eseguite), se si verifica un errore in qualche punto dello stesso.IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Rilevare se il puzzle è risolto”)Verse utilizza il successo/fallimento per prendere decisioni. Per maggiori dettagli su come Verse utilizza l'errore, vedi Fallimento.
- Quando deve verificare il dispositivo se il puzzle è stato risolto? Il momento migliore è quando l'array
LightsStateè stato appena aggiornato, il che avviene all'interno del metodoToggleLights(). Una volta che l'espressioneforha terminato di aggiornare l'arrayLightsState, chiama il metodoIsPuzzleSolved[]per determinare se il puzzle è risolto e quindi generare un oggetto, chiamandoItemSpawner.Enable(). PoichéIsPuzzleSolved[]è un'espressione fallibile (ecco perché il metodo ha la dicitura[]invece di()quando viene chiamato), deve essere chiamata in un contesto di fallimento. In questo esempio, il contesto di fallimento è un'espressioneif, in modo da poter eseguire in modo condizionale le espressioni, in base alla risoluzione del puzzle.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Impostazione delle luci all'indice {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() falso else: Light.TurnOn() vero if (set LightsState[LightIndex] = NewLightState): Logger.Print("Stato per le luci a {LightIndex} aggiornato") if (IsPuzzleSolved[]): Logger.Print("Puzzle risolto!") ItemSpawner.Enable() - Quindi, il metodo
IsPuzzleSolved()rileva se il puzzle è risolto. PoichéIsPuzzleSolved()è un contesto di fallimento, puoi utilizzare espressioni fallibili nel corpo del metodo senza dover usare un altro contesto di fallimento, come un'espressioneif. In questo caso, devi verificare se lo stato di ogni luce è uguale a quello del puzzle risolto. Per verificare se due valorilogicsono uguali, puoi usare l'operatore equals=, che è un'espressione fallibile. La prima volta che due valori che stai verificando non sono uguali, l'espressione fallisce, quindi il metodo restituisce un errore e ritorna al contesto del suo chiamante (in questo caso, l'espressioneifnel metodoToggleLights()).IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Rilevare se il puzzle è risolto”) for: LightIndex -> IsLightOn : LightsState IsLightOnInSolution := SolvedLightsState[LightIndex] do: IsLightOn = IsLightOnInSolution - Salva le modifiche in Visual Studio Code.
- Nella barra degli strumenti UEFN, fai clic su Compila gli script di Verse per compilare il codice.
- Per eseguire il playtest del livello, fai clic su Gioca nella barra degli strumenti UEFN.
Quando esegui il playtest del livello con le impostazioni mostrate in questo esempio, eseguire l'interazione una sola volta con tutti i pulsanti dovrebbe risolvere il puzzle e generare l'oggetto.

Rimozione dell'interazione con i pulsanti quando il puzzle è risolto
Dopo aver completato il puzzle, il giocatore non dovrebbe essere in grado di interagire con i pulsanti o di accendere/spegnere le luci. Questa sezione mostra come annullare la sottoscrizione a un evento, in modo che il gestore eventi non venga più chiamato quando un giocatore interagisce con il pulsante.
Quando chiami Subscribe() su un evento del dispositivo, la chiamata di funzione ha un risultato cancelable. La chiamata di Cancel() su una variabile cancelable annulla la funzione che gestisce l'evento, in modo che la funzione non venga più chiamata quando l'evento viene distribuito.
Per rimuovere le interazioni dei pulsanti una volta risolto il puzzle, attieniti ai passaggi seguenti:
- Aggiungi alla classe
tagged_lights_puzzleun campo variabile arraycancelabledenominatoButtonSubscriptionsper memorizzare il risultato della sottoscrizione all'evento di ogni pulsante e inizializza il campo con un array vuoto.var ButtonSubscriptions : []cancelable = array{} - Poiché questa è l'ultima istruzione dell'espressione
for, i suoi valori restituiti per tutte le iterazioni riuscite sono raccolti in un array del tipo di restituzione dell'espressione. Come spiegato in precedenza, il tipo di restituzione di una chiamataSubscribedi un evento ècancelable, questo rimanda ToggleLights ai risultatiforin un array dicancelable([]cancelable). Ciò corrisponde al tipoButtonsSubscription, quindi puoi assegnare il risultato dell'espressioneforall'arrayButtonsSubscription. Aggiungi questo codice nella funzioneOnBegin, dopoSetupPuzzleLights:OnBegin<override>()<suspends> : void = SetupPuzzleLights() set ButtonSubscriptions = for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: Button.InteractedWithEvent.Subscribe(button_event_handler{Indices := LightIndices, PuzzleDevice := Self}.OnButtonPressed) - Infine, ricorda che i pulsanti devono essere disabilitati, in modo che il giocatore non possa più modificare il
LightsState. Ciò si ottiene annullando la sottoscrizione ai gestoriInteractedWithEventdi ogni pulsante con una chiamata alla loro sottoscrizionecancelable. QuesteButtonSubscriptionssono state salvate quando i gestori eventi sono stati creati inOnBegin. Tutto ciò che resta da fare è scorrere questo array e chiamare l'annullamento per ogniButtonSubcription:ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Impostazione delle luci all'indice {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() falso else: Light.TurnOn() vero if (set LightsState[LightIndex] = NewLightState): Logger.Print("Stato per le luci a {LightIndex} aggiornato") if (IsPuzzleSolved[]): Logger.Print("Puzzle risolto!") ItemSpawner.Enable() for (ButtonSubscription : ButtonSubscriptions): ButtonSubscription.Cancel() - Salva le modifiche in Visual Studio Code.
- Nella barra degli strumenti UEFN, fai clic su Compila gli script di Verse per compilare il codice.
- Per eseguire il playtest del livello, fai clic su Gioca nella barra degli strumenti UEFN.
Con le proprietà predefinite, eseguire una volta l'interazione con tutti i pulsanti dovrebbe risolvere il puzzle, generare l'oggetto e disabilitare ulteriori interazioni con i pulsanti.
Passaggio successivo
Nell'ultimo passaggio di questo tutorial, potrai vedere lo script completo del tutorial e ottenere alcuni suggerimenti per modificare ulteriormente l'esempio.