Ajouter des tours

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Ajouter des manches vous permet de structurer le jeu en phases avec un point de départ et de fin clair afin que les joueurs puissent mesurer leur progression et avoir une opportunité périodique pour un terrain de jeu égal.Ceci est particulièrement important pour le jeu en équipe car il offre aux joueurs la possibilité de changer leur style de jeu en fonction de qui est dans leur équipe pendant cette manche.

En utilisant l'expérience de balise laser de échantillon comme référence, cette section du tutoriel vous apprend à utiliser et à personnaliser les fonctionnalités intégrées de Roblox pour structurer chaque tour, y compris des conseils de script sur :

  • Commencer une ronde en réinitialisant les points individuels et d'équipe, puis en générant des joueurs dans les zones de génération de leur équipe.
  • Personnalisation des variables qui définissent l'objectif pour la manche en haut de l'écran de chaque joueur.
  • Suivre les contributions du point du joueur pour le score de son équipe.
  • Activer des écrans d'interface utilisateur uniques en fonction de si l'équipe du joueur a gagné ou perdu la manche.
  • Mettre fin à une ronde en déconnectant les joueurs et en les faisant apparaître dans le lobby neutre.

Une fois que vous aurez terminé cette section, vous apprendrez à implémenter le comportement du blaster qui est à la fois précis et satisfaisant pour les joueurs.

Commencer la boucle

ServerScriptService > Gameplay > Rounds gère la plupart de la logique pour implémenter des tours, et commence par appeler la fonction startRoundLoopAsync() pour marquer le début d'une boucle de tours.Pendant que les joueurs rejoignent le lobby et attendent d'être répartis dans une équipe, appelle la fonction dans ServerScriptService > Gameplay > Évaluation pour réinitialiser à la fois le classement et les points d'équipe.

Évaluation

function Scoring.resetScores()
for _, player in Players:GetPlayers() do
player.leaderstats.Points.Value = 0
end
for _, team in Teams:GetTeams() do
team:SetAttribute(GuiAttribute.teamPoints, 0)
end
end

Maintenant que tout le monde commence à partir de zéro points, puis défini la propriété Neutre de la position d'apparition à zéro points à faux afin que seuls les joueurs avec la même propriété que la position d'apparition de la propriété puissent apparaître là.Parce que la propriété de l'emplacement d'apparition TeamColor est définie sur blanc au lieu des équipes de menthe ou de carnation rose de l'échantillon, cette configuration empêche tous les joueurs de se générer ou de réapparaître là pendant qu'une ronde est active.

Pour les joueurs qui sont actuellement dans le lobby, startRoundLoopAsync() passe tous les joueurs actuellement dans l'expérience à la fonction spawnPlayersInMap dans ServerScriptService > Gameplay > Rounds > spawnPlayersInMap pour trier et équilibrer tout le monde dans une équipe avec environ le même nombre de joueurs.

Pour tous les nouveaux joueurs qui rejoignent l'expérience après que le groupe du lobby ait été trié en équipe, startRoundLoopAsync() écoute l'événement Players.PlayerAdded:Connect et appelle à nouveau la fonction spawnPlayersInMap pour les ajouter à l'équipe avec le moins de joueurs.Pour plus d'informations sur ce processus, voir Configurer les emplacements d'apparition de la section précédente Apparition et réapparition du tutoriel.

Manches

-- Fait apparaître tous les joueurs sur la carte
neutralSpawn.Neutral = false
spawnPlayersInMap(Players:GetPlayers())
-- Générer de nouveaux joueurs sur la carte lorsqu'ils rejoignent
local playerAddedConnection = Players.PlayerAdded:Connect(function(player: Player)
spawnPlayersInMap({ player })
end)

Définir l'objectif

Maintenant que chaque joueur est dans l'arène avec ses coéquipiers, l'expérience doit fournir des instructions pour ce qu'il faut faire pour réussir dans la manche.L'expérience de balise laser d'échantillon résout cette exigence en fournissant une invite objective en haut de l'écran de chaque joueur avec des instructions claires sur ce que l'équipe doit faire pour gagner.

Bien que vous puissiez en savoir plus sur la façon de configurer et d'afficher le composant Objectif de l'interface utilisateur dans le curriculum de l'interface utilisateur, cette section se concentre sur la façon de mettre en œuvre l'objectif du but au début de la manche, en commençant par la façon de définir le nombre de points dont chaque équipe a besoin pour terminer la manche.

Bien que l'invite d'objectif à l'exécution informe les joueurs qu'ils doivent marquer trois points pour gagner, si vous examinez l'invite dans StarterGui > HUDGui , vous pouvez voir qu'elle contient plutôt une configurable « %d » pour la valeur du point.

"" %d " est une chaîne de remplacement que vous pouvez augmenter ou diminuer à tout moment pour répondre à vos propres exigences de jeu en mettant à jour la variable TEAM_SCORE_LIMIT dans ReplicatedStorage > TEAM_SCORE_LIMIT .Par exemple, si vous définissiez ce nombre à un niveau excessif élevé 200 , le compteur de points d'équipe et de prompt serait mis à jour en conséquence.

Límite de score d'équipe

local TEAM_SCORE_LIMIT = 200 -- ligne mise à jour, assurez-vous de revenir en retour
return TEAM_SCORE_LIMIT

Cette mise à jour simple de variable fonctionne au moment de l'exécution car lorsque le tour commence, ReplicatedStorage > HUDGuiSetup > Définir l'objectif exige le script du module afin qu'il puisse échanger la chaîne de remplacement dans l'objet de l'objectif de l'interface utilisateur.

Límite de score d'équipe

local TEAM_SCORE_LIMIT = require(ReplicatedStorage.TEAM_SCORE_LIMIT)
local function setObjective(gui: ScreenGui)
local bodyTextLabel = gui.Objective.ObjectiveDisplay.Body.BodyTextLabel
bodyTextLabel.Text = bodyTextLabel.Text:format(TEAM_SCORE_LIMIT)
end

Points de suivi

Maintenant que les joueurs ont un objectif pour la manche, l'expérience doit suivre les points de chaque équipe jusqu'à ce qu'ils atteignent leur objectif.Bien que le comportement par défaut du service Teams groupe automatiquement chaque joueur sous son équipe et ajoute les contributions de chaque joueur à leur score d'équipe, il est important de stocker et de surveiller les points dans un emplacement séparé pour le jeu en mode manche car si un joueur marque puis se déconnecte avant la fin de la manche, ses contributions sont déduites du classement dès qu'ils se déconnectent de l'expérience.

Pour garantir que cela ne se produise pas et que chaque contribution vers l'objectif de l'équipe soit préservée, ReplicatedStorage > HUDGuiSetup > Commencer à synchroniser les points d'équipe stocke tous les points séparément sous l'attribut dans le service.En tant qu'augmentations de teamPoints, ce script de module appelle la fonction startSyncingTeamPoints pour trouver le compteur d'équipe Class.GuiObjects dans la composante d'interface utilisateur Objective.

Lorsqu'il localise TeamACounter et TeamBCounter , il obtient leur attribut teamColor, qui correspond aux zones de génération d'équipe : TeamACounter affiche les points de l'équipe verte et TeamBCounter suit les points de l'équipe rose.

Commencer à synchroniser les points d'équipe

local function startSyncingTeamPoints(gui: ScreenGui)
for _, teamPointCounter in gui.Objective.TeamPointCounter:GetChildren() do
if not teamPointCounter:IsA("GuiObject") then
continue
end
local iconTeamColor = teamPointCounter:GetAttribute(GuiAttribute.teamColor)

Le script du module appelle ensuite sa fonction pour valider que l'attribut menthe du compteur d'équipe et l'attribut rose carnation du compteur d'équipe correspondent aux propriétés correspondantes du service.Si c'est le cas, il retourne les deux équipes.

Commencer à synchroniser les points d'équipe

local function getTeamFromTeamColor(teamColor: Color3): Team?
for _, team in Teams:GetTeams() do
if team.TeamColor == teamColor then
return team
end
end
return nil
end

Lorsque cela se produit, définit les objets des compteurs d'équipe à leurs valeurs correspondantes, et continue de les mettre à jour chaque fois qu'un joueur marque un point en marquant un autre joueur sur l'équipe adverse.

Commencer à synchroniser les points d'équipe

teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)
team:GetAttributeChangedSignal(GuiAttribute.teamPoints):Connect(function()
teamPointCounter.TextLabel.Text = team:GetAttribute(GuiAttribute.teamPoints)

Tout dans cette section jusqu'à présent s'est concentré sur la façon de suivre les points sur l'écran du joueur, mais il est important de revoir la logique qui gère les points de suivi sur le serveur afin qu'il sache quand une équipe atteint l'objectif et gagne la ronde.Si vous revisitez ServerScriptService > Gameplay > Évaluation , vous pouvez voir que le script du module commence par créer un événement liable, qui se déclenchera chaque fois qu'un joueur marquera un point.

Évaluation

local teamScoreChangedBindable = Instance.new("BindableEvent")
local Scoring = {
teamScoreChanged = teamScoreChangedBindable.Event,
}

Il appelle ensuite la fonction incrementScore, qui effectue les actions suivantes :

  • Prend l'équipe du joueur et sa valeur actuelle de points d'équipe sur l'objet du service, puis en ajoute un.
  • Prend le score individuel du joueur sur le classementsdes scores, et en ajoute un.
  • Lance l'événement bindable mentionné précédemment avec l'équipe du joueur et son score.

Ce processus garde efficacement le client et le serveur alignés quant aux scores individuels des joueurs et aux scores d'équipe.

Évaluation

function Scoring.incrementScore(player: Player, amount: number)
local team = player.Team
assert(team, `Player {player.Name} must be on a team to score a point, but has no team`)
local teamPoints = team:GetAttribute(GuiAttribute.teamPoints)
teamPoints += amount
team:SetAttribute(GuiAttribute.teamPoints, teamPoints)
local leaderstat = player.leaderstats.Points
leaderstat.Value += amount
teamScoreChangedBindable:Fire(team, teamPoints)
end

Afficher les résultats

Comme les joueurs se taguent les uns les autres et marquent des points pour leur équipe, ServerScriptService > Gameplay > Rounds vérifie si l'équipe qui a marqué a atteint l'objectif de la manche.Si le score de leur équipe est inférieur à la variable TEAM_SCORE_LIMIT de ReplicatedStorage > TEAM_SCORE_LIMIT , le serveur continue d'attendre jusqu'à ce que l'une des équipes marque à nouveau.

Cependant, une fois que le score d'une équipe atteint la variable , le script déclenche une instance d'événement avec le nom du joueur et son équipe.

Manches

-- Vérifiez si la manche est terminée après chaque score
local team: Team
local score: number = 0
while score < TEAM_SCORE_LIMIT do
team, score = Scoring.teamScoreChanged:Wait()
end
-- Afficher l'équipe gagnante
for _, player in Players:GetPlayers() do
-- Envoyer à quelle équipe le joueur appartient à la fin de la manche
-- parce que l'équipe du joueur est sur le point d'être supprimée, donc le client
-- ne pourra pas vérifier son propre équipe
roundWinnerRemote:FireClient(player, team, player.Team)
end

Le script ReplicatedStorage > RoundResultsGuiSetup sur chaque liste de clients écoute cette instance d'événement roundWinnerRemote pour qu'il puisse :

  • Affichez un écran d'interface utilisateur unique StarterGui > RoundResultsGui qui annonce les résultats de la manche et si le joueur faisait partie de l'équipe gagnante.
  • Jouez un clip audio de victoire ou de défaite.

Par exemple, si un joueur est dans l'équipe qui a marqué le point gagnant, il reçoit plusieurs formes de commentaires sur les résultats de la manche sous la forme d'un écran d'interface utilisateur qui affiche le texte de la victoire et un clip audio qui joue un son joyeux.Inversement, si un joueur n'est pas dans l'équipe qui a marqué le point gagnant, il reçoit un écran d'interface utilisateur qui affiche le texte de la défaite et un clip audio qui joue un son sinistre.

Commentaires de victoire
>

Vaincre les commentaires
RoundResultsGuiSetup

local function onRoundWinner(winner: Team, localTeam: Team?)
local victoryDefeatText = "Round ended!"
if localTeam then
-- Si notre équipe gagne, nous afficherons la victoire ! Sinon, afficher la défaite...
local isVictory = winner == localTeam
if isVictory then
victorySound:Play()
victoryDefeatText = VICTORY_TEXT
else
defeatSound:Play()
victoryDefeatText = DEFEAT_TEXT
end
end

Réinitialiser les équipes

En même temps que ServerScriptService > Gameplay > Rounds vérifie que une équipe a atteint l'objectif de la manche et déclenche l'affichage approprié de l'interface utilisateur pour chaque joueur, il transporte également tous les joueurs de l'arène au lobby en les déconnectant de la manche.Cela lance le processus de fin officielle de la manche et de réinitialisation des deux équipes.

En utilisant la même logique dans Configurer les lieux d'apparition , Rounds puis défini la propriété Neutre de la position d'apparition à vrai afin que les joueurs puissent apparaître là indépendamment de leur statut d'équipe.Cela signifie que le lobby devient le seul endroit où les joueurs peuvent apparaître après avoir été déconnectés de la manche.

Manches

-- Envoyer tout le monde dans le lobby
playerAddedConnection:Disconnect()
neutralSpawn.Neutral = true
spawnPlayersInLobby(Players:GetPlayers())

Après avoir attendu dix secondes pour une pause, le script du serveur manches lance ensuite la boucle à nouveau en réinitialisant les scores de tous et en les classant dans de nouvelles équipes.L'échantillon répète à nouveau ce processus cyclique jusqu'à ce qu'il n'y ait pas de joueurs dans le serveur.

Maintenant que les joueurs peuvent apparaître sur la carte avec leur propre équipe et jouer un tour complet, la section suivante vous enseigne sur les scripts derrière le comportement de chaque blaster.