Wenn du diesen Schritt im Tutorial Time Trial: Pizza Pursuit abgeschlossen hast, weißt du, wie du den Punktestand verwaltest, wenn ein Spieler Gegenstände aufhebt und abgibt, und wie du die Benutzeroberfläche aktualisierst, um diese Punktzahlen anzuzeigen. Um mehr über die Erstellung einer In-Game-UI in Verse zu erfahren, siehe Creating an In-Game UI.
Die Punkteanpassung verfolgt und zeigt an:
Gesamtpunkte: Stellt die Gesamtpunkte dar, die der Spieler in-game erzielt hat.
Ausstehende Punkte: Stellt die Punkte dar, die der Spieler für den aktuellen Satz von Abholungen angesammelt hat.
Abholpunkt-Level: Repräsentiert das aktuelle Abholpunkt-Level.
Erstellen der UI
Befolge diese Schritte, um die UI für die Punkteanpassung in Verse zu erstellen:
Erstelle eine neue leere Verse-Datei und nenne sie score_manager.verse.
Erstelle eine neue Klasse mit dem Namen
score_managerund füge der Klasse die folgenden Felder hinzu:Ein optionaler
AgentnamensMaybePlayer, um einen Verweis auf den Spieler zu speichern.MaybePlayer<internal> : ?agent = falseEin optionales
player_uimit dem NamenMaybePlayerUI, um einen Verweis auf die Benutzeroberfläche des Spielers zu speichern.MaybePlayerUI<internal> : ?player_ui = falseEin
score_manager_device, um eine Referenz für das Punkteanpassung-Gerät zu speichern, um das diese Klasse herum aufgebaut ist. (Hinweis: Dies ist kein editierbarer Verweis, da dieser mit dem von Verse erstellten Gerätgame_coordinator_deviceverbunden sein muss.ScoreManagerDevice<internal> : score_manager_device = score_manager_device{}Eine ganzzahlige Variable namens
TotalGameScore, die alle Punkte darstellt, die der Spieler im gesamten Spiel erzielt hat.var TotalGameScore<private> : int = 0Eine ganzzahlige Variable
PendingScore, die die Punkte angibt, die der Spieler derzeit für diesen Satz von Abholungen angesammelt hat.var PendingScore<private> : int = 0Eine ganzzahlige Variable mit dem Namen
PickupLevel, die den aktuellen Abhol-Level darstellt.var PickupLevel<private> : int = 0
Deine `score_manager`-Klassendefinition sollte nun wie folgt aussehen:
score_manager := class: MaybePlayer<internal> : ?agent = false MaybePlayerUI<internal> : ?player_ui = false ScoreManagerDevice<internal> : score_manager_device = score_manager_device{} var TotalGameScore<private> : int = 0 var PendingScore<private> : int = 0 var PickupLevel<private> : int = 0Erstelle die UI, wenn die Klasse zum ersten Mal erstellt wird. Dazu wird ein
block-Ausdruck in die Klassendefinition eingefügt, der immer dann ausgeführt wird, wenn du eine Instanz der Klasse erstellst. Füge die folgenden Variablen für die Erstellung der UI hinzu:Eine
canvas-Variable mit dem NamenCanvas, die den Bezeichnerinternalhat, um das benutzerdefinierte Canvas-Widget zu speichern.var Canvas<internal> : canvas = canvas{}Ein
text_blockmit dem NamenTotalGameScoreWidgetund dem Bezeichnerinternal, um das Textwidget für die Anzeige aller Punkte, die der Spieler im Spiel insgesamt erzielt hat, zu speichern, wie durch die VariableTotalGameScoredargestellt. Setzt die Standardtextfarbe des Textblocks auf Weiß.TotalGameScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White}Ein
text_blockmit dem NamenPendingScoreWidgetund dem Bezeichnerinternal, um das Textwidget für die Anzeige der Punkte zu speichern, die der Spieler derzeit für diesen Satz von Abholungen angesammelt hat, wie durch die VariablePendingScoredargestellt. Setzt die Standardtextfarbe des Textblocks auf Weiß.PendingScoreWidget<internal> : text_block = text_block{}Ein
text_blockmit dem NamenPickupLevelWidgetund dem Bezeichnerinternal, um das Textwidget für die Anzeige des aktuellen Abhol-Levels zu speichern, das durch die VariablePickupLeveldargestellt wird. Setzt die Standardtextfarbe des Textblocks auf Weiß.PickupLevelWidget<internal> : text_block = text_block{}Eine Funktion, die eine
messagenamensTotalGameScoreTextzurückgibt, die einen lokalisierbaren Text erzeugt, der in der Benutzeroberfläche für alle Punkte angezeigt werden kann, die der Spieler im gesamten Spiel erzielt hat.TotalGameScoreText<localizes>(CurrentTotalGameScore : int) : message = "Total Points: {CurrentTotalGameScore}"Eine Funktion, die eine
messagenamensPendingScoreTextzurückgibt, die einen lokalisierbaren Text erzeugt, der in der Benutzeroberfläche für die Punkte angezeigt werden kann, die der Spieler derzeit für diesen Satz von Abholungen angesammelt hat.PendingScoreText<localizes>(CurrentPendingScore : int) : message = "Pending Points: {CurrentPendingScore}"Eine Funktion, die eine
messagenamensPickupLevelTextzurückgibt, die einen lokalisierbaren Text erzeugt, der in der Benutzeroberfläche für das aktuellen Abhol-Level angezeigt werden kann.PickupLevelText<localizes>(CurrentPickupLevel : int) : message = "Pickup Level: {CurrentPickupLevel}"Füge einen
block-Ausdruck hinzu, der das Canvas-Widget erstellt und den Text vertikal auf der linken Seite des Bildschirms positioniert.<# Da wir den Canvas während der Lebensdauer der Punkteanpassung nicht neu erstellen werden, machen wir das einmal, wenn ein Objekt dieses Typs erstellt wird. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := true Widget := stack_box: Orientation := orientation.Vertical Slots := array: stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := TotalGameScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PendingScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PickupLevelWidget
Dein Code für
score_managersollte nun wie folgt aussehen:verwendet { /UnrealEngine.com/Temporary/UI } verwendet { /Fortnite.com/UI } verwendet { /Verse.org/Colors } score_manager := class: var Canvas<internal> : canvas = canvas{} TotalGameScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} PendingScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} PickupLevelWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} MaybePlayer<internal> : ?agent = false MaybePlayerUI<internal> : ?player_ui = false ScoreManagerDevice<internal> : score_manager_device = score_manager_device{} PickupLevelText<private><localizes>(InLevel : int) : message = "Pickup Level: {InLevel}" PendingScoreText<private><localizes>(InPoints : int) : message = "Pending Points: {InPoints}" TotalGameScoreText<private><localizes>(InPoints : int) : message = "Total Points: {InPoints}" var TotalGameScore<private> : int = 0 var PendingScore<private> : int = 0 var PickupLevel<private> : int = 0 <# Da wir den Canvas während der Lebensdauer der Punkteanpassung nicht neu erstellen werden, machen wir das einmal, wenn ein Objekt dieses Typs erstellt wird. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := true Widget := stack_box: Orientation := orientation.Vertical Slots := array: stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := TotalGameScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PendingScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PickupLevelWidgetErstelle eine Funktion mit dem Namen
UpdateUI(), die den Parameterprivatehat und die den Text in der Benutzeroberfläche mit den neuesten Punktwerten und dem aktuellen Abhol-Level aktualisiert.UpdateUI<private>() : void = if (PlayerUI := MaybePlayerUI?): PickupLevelWidget.SetText(PickupLevelText(PickupLevel)) PendingScoreWidget.SetText(PendingScoreText(PendingScore)) PendingScoreWidget.SetText(TotalGameScoreText(TotalGameScore))Erstelle eine Funktion namens
AddScoreManagerToUI(), die die UI des Spielers mit der benutzerdefinierten UI der Punkteanpassung aktualisiert.AddScoreManagerToUI<public>() : void = if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) UpdateUI()Erstelle eine Funktion für jeden Wert, der auf der Benutzeroberfläche angezeigt wird, damit die Spielschleife die Werte aktualisieren kann:
Eine Funktion mit dem Namen
AddPendingScoreToTotalScore(), die den Bezeichnerpublichat. Diese Funktion sollte den ausstehenden Punktestand zum Gesamtspielstand addieren und den Wert für den ausstehenden Punktestand auf0zurücksetzen. Du kannst das Zurücksetzen vonPendingScoreund das Aktualisieren der Benutzeroberfläche durchdeferverzögern, nachdem derTotalGameScoreaktualisiert wurde. Dadurch wird vermieden, dass eine temporäre Variable verwendet wird, um den Wert vonPendingScorezu halten, bevor er zurückgesetzt wird.Verse<# Adds PendingScore to TotalGameScore and resets PendingScore to 0.#> AddPendingScoreToTotalScore<public>() : void = defer: set PendingScore = 0 UpdateUI() set TotalGameScore += PendingScoreEine Funktion mit dem Namen
UpdatePendingScore(), die den Parameterpublicund einen ganzzahligen Parameter mit dem NamenPointshat, den die Funktion zum aktuellen ausstehenden Ergebnis hinzufügt.Verse<# Adds the given amount of points to the pending points. #> UpdatePendingScore<public>(Points : int) : void = set PendingScore += Points UpdateUI()Eine Funktion mit dem Namen
UpdatePickupLevel, die den Bezeichnerpublicund einen Integer-Parameter mit dem NamenLevelhat, der den neuen Wert für das aktuellen Abhol-Level darstellt.VerseUpdatePickupLevel<public>(Level : int) : void = set PickupLevel = Level UpdateUI()Erstelle eine Funktion mit dem Namen
AwardScore(), die den Bezeichnerpublichat. Diese Funktion vergibt mit dem Punkteanpassungsgerät den Punktestand an den Spieler und aktiviert das Gerät.Verse<# Awards the score to the player with the Score Manager device, by activating it. #> AwardScore<public>() : void = ScoreManagerDevice.SetScoreAward(TotalGameScore) if (AwardedPlayer := MaybePlayer?): ScoreManagerDevice.Activate(AwardedPlayer)
Deine
score_manager-Klasse sollte nun wie folgt aussehen:Versescore_manager := class: <# Since we won't recreate the canvas during the score manager lifetime, do it once anytime an object of this type is created.> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := trueNachdem du nun deine
score_manager-Klasse erstellt hast, erstelle einen Constructor für die Klasse, um die Spielervariablen aus dem Spiel zu initialisieren. Beachte, dass du die Spielerreferenz vonagentnachplayertype cast musst, um eine Referenz auf die UI des Spielers zu erhalten.VerseMakeScoreManager<constructor><public>(InPlayer : agent, InScoreManagerDevice : score_manager_device) := score_manager: MaybePlayer := option{InPlayer} MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}Deine Datei score_manager.verse sollte nun wie folgt aussehen:
Verseusing { /UnrealEngine.com/Temporary/SpatialMath} using { /UnrealEngine.com/Temporary/UI } using { /Fortnite.com/Devices } using { /Fortnite.com/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation } MakeScoreManager<constructor><public>(InPlayer : agent, InScoreManagerDevice : score_manager_device) := score_manager: MaybePlayer := option{InPlayer} MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
Aktualisieren des Spielstands und der Benutzeroberfläche in der Spielschleife
Folge diesen Schritten, um deine UI während des Spiels in der Datei game_coordinator_device.verse zu aktualisieren:
Füge der Klasse
game_coordinator_devicedie folgenden Eigenschaften hinzu:Eine
score_manager-Variable mit dem NamenScoreManager, die den Bezeichnerprivatehat. Diese Instanz verwaltet den Punktestand und die Benutzeroberfläche des Spielers.var ScoreManager<private> : score_manager = score_manager{}Ein editierbares
score_manager_device, das du auf das Punkteanpassung-Gerät im Level setzen kannst. Dies ist das Gerät, das die Klassescore_managerverwenden wird.@editable ScoreManagerDevice<public> : score_manager_device = score_manager_device{}Ein editierbares Integer-Array mit dem Namen
PointsForPickupLevel, das den Bezeichnerpublichat, um die Punkte zu definieren, die der Spieler für jedes Abhol-Level erreichen kann.@editable # Zeigt an, wie viele Punkte eine Abholung auf der Grundlage ihres Abhol-Levels wert ist. PointsForPickupLevel<public> : []int = array{1, 2, 3}
Initialisiere in der Funktion
StartGamedie Punkteanpassung-Variable, indem du den ConstructorMakeScoreManager()mit einem Verweis auf den Spieler und das Punkteanpassung-Gerät aufrufst, und generiere die Benutzeroberfläche, die der Spieler sehen kann.VerseStartGame<private>()<suspends> : void = Logger.Print("Trying to start the game...") # We construct a new countdown_timer that'll countdown from InitialCountdownTime once started. # Also construct a new score_manager that'll keep track of the player's score and pickup level. # The countdown_timer and score_manager require a player to show their UI to. # We should have a valid player by now: the one that entered the vehicle, triggering the game start. if (ValidPlayer := MaybePlayer?): Logger.Print("Valid player, starting game...")In der Funktion
PickupDeliveryLoop()der Spielschleife wird die Benutzeroberfläche immer dann aktualisiert, wenn sich das Abhol-Level ändert und der Spieler eine Abholung oder Lieferung abschließt:VersePickupDeliveryLoop<private>()<suspends> : void = PickupZonesTags : []pickup_zone_tag = array{pickup_zone_level_1_tag{}, pickup_zone_level_2_tag{}, pickup_zone_level_3_tag{}} MaxPickupLevel := PickupZonesTags.Length - 1 FirstPickupZoneCompletedEvent := event(){} loop: var PickupLevel : int = 0 var IsFirstPickup : logic = true # Every time the loop restarts, we should reset the pickup level UI through the ScoreManager.Wenn der Countdown abgelaufen ist, erhält der Spieler seinen Punktestand. Rufe in
HandleCountdownEnd()die FunktionScoreManager.AwardScore()auf.HandleCountdownEnd<private>(InPlayer : player)<suspends>:void= TotalTime := CountdownTimer.CountdownEndedEvent.Await() ScoreManager.AwardScore() EndGame.Activate(InPlayer)Deine Datei game_coordinator_device.verse sollte nun wie folgt aussehen:
Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } using { /Fortnite.com/Vehicles } using { /Fortnite.com/Characters } using { /Fortnite.com/Playspaces } using { /Verse.org/Random } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath } using { /EpicGames.com/Temporary/Curves } using { /Verse.org/Simulation/Tags }