Projet de référence pour les plantes

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

Plante est une expérience de référence où les joueurs plantent et arrosent des graines, afin qu'ils puissent récolter et vendre les plantes résultantes plus tard.

Plant project banner

Le projet se concentre sur les cas d'utilisation communs que vous pourriez rencontrer lors du développement d'une expérience sur Roblox.Lorsque cela est applicable, vous trouverez des notes sur les compromis, les concessions et la raison des différents choix d'implémentation, afin que vous puissiez prendre la meilleure décision pour vos propres expériences.

Obtenir le fichier

  1. Accédez à la page d'expérience Plante.
  2. Cliquez sur le bouton et Éditer dans le studio .

Utiliser des cas

Plante couvre les cas d'utilisation suivants :

  • Persistance des données de session et des données du joueur
  • Gestion de la vue de l'interface utilisateur
  • Réseau client-serveur
  • Expérience utilisateur pour la première fois (FTUE)
  • Achats de devises dures et douces

En outre, ce projet résout des ensembles de problèmes plus étroits qui sont applicables à de nombreuses expériences, y compris :

  • Personnalisation d'une zone dans l'endroit qui est associé à un joueur
  • Gérer la vitesse de déplacement du personnage du joueur
  • Créer un objet qui suit les caractères autour
  • Détection de la partie du monde dans laquelle se trouve un personnage

Notez qu'il y a plusieurs cas d'utilisation dans cette expérience qui sont trop petits, trop nichés ou ne démontrent pas de solution à un défi de conception intéressant ; ceux-ci ne sont pas couverts.

Structure du projet

La première décision lors de la création d'une expérience est de décider comment structurer le projet, qui comprend principalement où placer des instances spécifiques dans le modèle de données et comment organiser et structurer les points d'entrée pour le client et le serveur.

Modèle de données

La table suivante décrit les services de conteneur dans les instances du modèle de données dans lesquelles ils sont placés.

ServiceTypes d'instances
Workspace

Contient des modèles statiques représentant le monde 3D, plus précisément des parties du monde qui ne appartiennent à aucun joueur.Vous n'avez pas besoin de créer, de modifier ou de supprimer dynamiquement ces instances au moment de l'exécution, donc il est acceptable de les laisser ici.:

Il y a aussi un modèle vide Folder , auquel les modèles de ferme des joueurs seront ajoutés au moment de l'exécution.

Lighting

Effets atmosphériques et de lumière.

ReplicatedFirst

Contient le sous-ensemble le plus petit possible d'instances nécessaires pour afficher l'écran de chargement et initialiser le jeu.Plus il y a d'instances placées dans ReplicatedFirst, plus le temps d'attente avant qu'elles se reproduisent avant le code dans ReplicatedFirst puisse s'exécuter est lancer.:

  • Dans le dossier instances existe l'interface de chargement interface utilisateur graphique.:
  • Dans le dossier Source existe le code de la page de chargement et le code nécessaire pour attendre que le reste du jeu se charger.Le start``Class.LocalScript est le point d'entrée pour tout le code côté client dans le projet.
ReplicatedStorage

Sert de conteneur de stockage pour toutes les instances pour lesquelles l'accès est requis à la fois sur le client et sur le serveur.:

  • Dans le dossier dépendances il existe certaines bibliothèques tierces utilisées par le projet.:
  • Dans le dossier Instances il existe une large gamme d'instances préfabriquées utilisées par différentes classes dans le jeu.:
  • Dans le dossier Source il existe tout le code non nécessaire pour le processus de chargement qui doit être accessible à la fois du client et du serveur.
ServerScriptService

Contient un Script servant de point d'entrée pour tout le code côté serveur dans le projet.

ServerStorage

Sert de conteneur de stockage pour toutes les instances qui ne doivent pas être répliquées au client.:

  • Dans le dossier instances il existe un modèlisationde modèle ferme .Une copie de ceci est placée dans Workspace lorsque le joueur rejoint le jeu, où elle sera répliquée à tous les joueurs.:
  • Dans le dossier Source existe tout le code qui est exclusif au serveur.
SoundService

Contient les objets Sound utilisés pour les effets sonores dans le jeu.En dessous de SoundService , ces objets Sound n'ont pas de position et ne sont pas simulés dans l'espace 3D.

Points d'entrée

La plupart des projets organisent le code à l'intérieur d'un réutilisable ModuleScripts qui peut être importé dans toute la base de code.ModuleScripts sont réutilisables mais ne s'exécutent pas par posséder; ils doivent être importés par un Script ou LocalScript .De nombreux projets Roblox auront un grand nombre d'objets Script et LocalScript, chacun appartenant à un comportement ou à un système spécifique dans le jeu, créant plusieurs points d'entrée.

Pour le microjeu Plante, une approche différente est mise en œuvre via une seule LocalScript qui est le point d'entrée pour tout le code client, et une seule Script qui est le point d'entrée pour tout le code serveur.La bonne approche pour votre projet dépend de vos exigences, mais un seul point d'entrée fournit un plus grand contrôle sur l'ordre dans lequel les systèmes sont exécutés.

Les listes suivantes décrivent les compromis des deux approches :

  • Un seul Script et un seul LocalScript couvre le code serveur et client respectivement.
  • Un meilleur contrôle de l'ordre dans lequel différents systèmes sont démarrés car tout le code est initialisé à partir d'un seul script.
  • Peut passer des objets par référence entre les systèmes.

Architecture système de haut niveau

Les systèmes de niveau supérieur dans le projet sont détaillés ci-dessous.Certains de ces systèmes sont substantiellement plus complexes que d'autres, et dans de nombreux cas, leur fonctionnalité est abstraite à travers une hiérarchie d'autres Classes.

Plant project systems architecture diagram

Chacun de ces systèmes est un "singleton", dans le sens où c'est une classe non instantanée initialisée par le script client ou serveur pertinent start.Vous pouvez en savoir plus sur le modèle singleton plus tard dans ce guide.

Serveur

Les systèmes suivants sont associés au serveur.

SystèmeAvertissement
Réseau
  • Crée toutes les RemoteEvent et RemoteFunction instances.:
  • Expose des méthodes pour l'envoi et l'écoute de messages du client.:
  • Valider le type pour les arguments reçus du client en temps d'exécution.
Serveur de données joueur
  • Sauvegarde et charge les données persistantes du joueur en utilisant DataStoreService .:
  • Stocke les données du joueur en mémoire et réplique les mutations au client.:
  • Expose des signaux et des méthodes pour s'abonner, interroger et mettre à jour les données du joueur.
Marché
  • Gère les transactions de devises douces du client.

  • Expose une méthode pour vendre des plantes récoltées.

Gestionnaire de groupe de collision

Attribue des modèles de personnage de joueur à des groupes de collision .:

  • Configure des groupes de collision afin que les personnages des joueurs ne puissent pas se heurter aux wagons de plantes.
Serveur de gestionnaire de ferme
  • Recrée le modèle de ferme d'un joueur à partir de ses données de joueur lorsqu'il rejoint le jeu.:
  • Élimine le modèle de ferme lorsqu'un joueur quitte.:
  • Mise à jour des données du joueur lorsque la ferme d'un joueur est modifiée.:
  • Expose une méthode pour accéder à la classe Ferme associée à un joueur donné.
Conteneur d'objets joueurs
  • Crée différents objets associés à la durée de vie d'un joueur et fournit une méthode pour les récupérer.
Joueurs de balise
Serveur FtueManager
  • Pendant l'FTUE, exécute chaque étape et attendez qu'elle soit terminée.
Générateur de caractères
  • Réapparait les personnages lorsqu'ils meurent.Notez que Players.CharacterAutoLoads a été désactivé afin que la génération soit suspendue jusqu'à ce que les données du joueur soient chargées.

Client

Les systèmes suivants sont associés au client.

SystèmeAvertissement
Réseau
  • Attend que le serveur crée toutes les RemoteEvent et RemoteFunction instances.:
  • Expose des méthodes pour envoyer et écouter des messages vers et depuis le serveur.:
  • Applique la validation du type de paramètre d'exécution.:
  • Exécute pcall() sur les fonctions à distance.
JoueurDataClient
  • Stocke les données du joueur local dans la mémoire.:
  • Expose des méthodes et des signaux pour rechercher et s'abonner aux modifications des données du joueur.
Client du marché
  • Expose une méthode pour demander au serveur d'acheter un article pour une monnaiedouce.
Gestionnaire de saut de marche locale
  • Expose des méthodes pour modifier le WalkSpeed ou JumpHeight d'un personnage via des multiplicateurs pour éviter les conflits lors de la modification de ces valeurs à partir de plusieurs endroits.
Clienteur de ferme
  • Écoute les balises spécifiques CollectionService qui sont appliquées aux instances et crée des « composants » ajoutant un comportement à ces instances.Un « composant » fait référence à une classe créée lorsqu'une balise CollectionService est ajoutée à une instance et détruite lorsqu'elle est supprimée ; ces derniers sont utilisés pour les invites CTA dans la ferme et diverses classes télégraphiant l'état de la ferme au joueur.
Installation de l'interface utilisateur
  • Initialise toutes les couches d'interface utilisateur.:
  • Configurez certaines couches pour qu'elles soient visibles uniquement dans les sections physiques du monde du jeu.:
  • Relie un effet de caméra spécial pour quand les menus sont activés.
Clienteur FtueManager
  • Configure les étapes FTUE sur le client.
Course de caractères
  • Utilise LocalWalkJumpManager pour augmenter WalkSpeed lorsqu'un personnage de joueur est à l'extérieur de sa ferme.

Communication client-serveur

La plupart des expériences Roblox impliquent un élément de communication entre le client et le serveur.Cela peut inclure la demande du client au serveur d'effectuer une certaine action et la réplication des mises à jour du serveur au client.

Dans ce projet, la communication client-serveur est maintenue aussi générique que possible en limitant l'utilisation des objets RemoteEvent et RemoteFunction pour réduire le nombre de règles spéciales à suivre.Ce projet utilise les méthodes suivantes, par ordre de préférence :

  • Réplication via le système de données du joueur .
  • Réplication via attributs.
  • Réplication via des balises .
  • Messagerie directement via le module Réseau .

Réplication via le système de données du joueur

Le système de données joueur permet d'associer des données au joueur qui persiste entre les sessions de sauvegarde .Ce système fournit une réplication du client au serveur et un ensemble d'API qui peut être utilisé pour interroger des données et s'abonner aux modifications, ce qui le rend idéal pour répliquer les modifications de l'état du joueur du serveur au client.

Par exemple, plutôt que de tirer un bespoke UpdateCoins``Class.RemoteEvent pour dire au client combien de pièces il a, vous pouvez appeler le suivant et laisser le client s'abonner à celui-ci via l'événement PlayerDataClient.updated.


PlayerDataServer:setValue(player, "coins", 5)

Bien sûr, cela n'est utile que pour la réplication serveur-client et pour les valeurs que vous souhaitez persister entre les sessions, mais cela s'applique à un nombre surprenant de cas dans le projet, y compris :

  • L'étape FTUE actuelle
  • inventairedu joueur
  • La quantité de pièces que le joueur a
  • L'état de la ferme du joueur

Réplication via des attributs

Dans des situations où le serveur doit répliquer une valeur personnalisée au client qui est spécifique à un donné Instance, vous pouvez utiliser les attributs.Roblox réplique automatiquement les valeurs d'attribut, vous n'avez donc pas besoin de maintenir des chemins de code pour répliquer l'état associé à un objet.Un autre avantage est que cette réplication se produit aux côtés de l'instance elle-même.

Cela est particulièrement utile pour les instances créées au moment de l'temps d'exécution, car les attributs définis sur une nouvelle instance avant qu'elle ne soit parentée au modèle de données se reproduiront atomiquement avec l'instance elle-même.Cela contourne tout besoin d'écrire du code pour "attendre" que des données supplémentaires soient répliquées via un RemoteEvent ou StringValue .

Vous pouvez également lire directement les attributs du modèlisationde données, du client ou du serveur, avec la méthode GetAttribute() , et vous abonner aux modifications avec la méthode GetAttributeChangedSignal().Dans le projet Plante, cette approche est utilisée, entre autres, pour répliquer le statut actuel des plantes aux clients.

Réplication via des balises

CollectionService vous permet d'appliquer une balise de chaîne à un Instance . Ceci est utile pour catégoriser des instances et de répliquer cette catégorisation au client.

Par exemple, la balise CanPlant est appliquée sur le serveur pour indiquer au client qu'un pot donné est capable de recevoir une plante.

Message directement via le module réseau

Pour les situations où aucune des options précédentes ne s'applique, vous pouvez utiliser des appels réseau personnalisés via le module réseau .C'est la seule option dans le projet qui permet la communication client-serveur et est donc la plus utile pour transmettre les demandes du client et recevoir une réponse du serveur.

Plante utilise des appels réseau directs pour une variété de demandes de clients, y compris :

  • Arroser une plante
  • Planter une graine
  • Acheter un item

L'inconvénient de cette approche est que chaque message individuel nécessite une configuration sur mesure qui peut augmenter la complexité du projet, bien que cela ait été évité partout où cela a été possible, notamment pour la communication du serveur au client.

Classes et singletons

Les classes dans le projet Plante peuvent être créées et détruites, comme des instances sur Roblox.Sa syntaxe de classe est inspirée de l'approche idiomatique de Lua à la programmation orientée objet avec un certain nombre de modifications pour activer le assistancede vérification de type strict.

Instantiation

De nombreuses classes dans le projet sont associées à une ou plusieurs Instances.Les objets d'une classe donnée sont créés en utilisant une méthode new() , conforme à la façon dont les instances sont créées dans Roblox en utilisant Instance.new() .

Ce modèle est généralement utilisé pour les objets où la classe a une représentation physique dans le modèlisationde données, et que la classe étend sa fonctionnalité.Un bon exemple est BeamBetween qui crée un objet Beam entre deux objets donnés Attachment et garde ces accessoires orientés afin que le rayon soit toujours dirigé vers le haut.Ces instances pourraient être clonées à partir d'une version préfabriquée dans ReplicatedStorage ou être transmises dans new() en tant qu'argument et stockées à l'intérieur de l'objet sous self .

Instances correspondantes

Comme noté ci-dessus, de nombreuses classes dans ce projet ont une représentation de modèle de données, une instance qui correspond à la classe et est manipulée par elle.

Plutôt que de créer ces instances lorsqu'un objet de classe est instancé, le code choisit généralement de Clone() une version préfabriquée du Instance stockée sous ReplicatedStorage ou ServerStorage .Bien qu'il soit possible de sérialiser les propriétés de ces instances et de les créer à partir de zéro dans les fonctions de classe new(), le faire rendrait l'édition des objets très laborieuse et les rendrait plus difficiles à analyser pour un lecteur.De plus, le clonage d'une instance est généralement une opération plus rapide que la création d'une nouvelle instance et la personnalisation de ses propriétés en temps d'exécution.

Composition

Bien que l'héritage soit possible dans Luau en utilisant métatables, le projet choisit plutôt d'autoriser les classes à s'étendre les unes aux autres par le biais de composition .Lors de la combinaison de classes par composition, l'objet « enfant » est instancié dans la méthode new() de la classe et est inclus en tant que membre sous self .

Pour un exemple de cela en action, voir la classe CloseButton qui enveloppe la classe Button.

Nettoyage

Semblable à la façon dont un Instance peut être détruit avec la méthode Destroy(), les classes qui peuvent être instanciées peuvent également être détruites.La méthode destructeur pour les classes de projet est avec une minuscule pour la cohérence des méthodes de l'ensemble du code source, ainsi que pour distinguer les classes du projet et les instances Roblox.

Le rôle de la méthode destroy() est de détruire toutes les instances créées par l'objet, de déconnecter toutes les connexions et d'appeler destroy() sur tous les objets enfants.C'est particulièrement important pour les connexions car les instances avec des connexions actives ne sont pas nettoyées par le collecteur de déchets Luau, même si aucune référence à l'instance ou aucune connexion à l'instance ne reste.

Singletons

Les singletons, comme le nom l'indique, sont des classes pour lesquelles un seul objet peut jamais exister.Ils sont l'équivalent des services de Roblox pour le projet Services.Plutôt que de stocker une référence à l'objet singleton et de le transmettre dans le code Luau, Plante profite du fait que la nécessité d'un ModuleScript cache sa valeur retournée.Cela signifie que la nécessité du même singleton ModuleScript de différents endroits fournit de manière cohérente le même objet retourné.La seule exception à cette règle serait si différents environnements (client ou serveur) accédaient au ModuleScript .

Les singletons sont distingués des classes instantanées par le fait qu'ils n'ont pas de méthode new().Plutôt, l'objet avec ses méthodes et son état est retourné directement via le ModuleScript .Comme les singletons ne sont pas instantanés, la syntaxe self n'est pas utilisée et les méthodes sont plutôt appelées avec un point ( . ) plutôt qu'une virgule ( : ).

Inférence de type strict

Luau prend en charge le saisissement progressif ce qui signifie que vous êtes libre d'ajouter des définitions de type optionnelles à certaines ou à toutes vos modifications de code.Dans ce projet, le contrôle de type strict est utilisé pour chaque script.C'est l'option la moins restrictive pour l'outil d'analyse des scripts de Roblox et donc la plus susceptible de détecter les erreurs de type avant l'exécution.

Syntaxe de classe saisie

La démarche établie pour créer des classes en Lua est bien documentée, cependant elle n'est pas bien adaptée au fort typage Luau.Dans Luau, l'approche la plus simple pour obtenir le type d'une classe est la méthode typeof() :


type ClassType = typeof(Class.new())

Cela fonctionne, mais ce n'est pas très utile lorsque votre classe est initialisée avec des valeurs qui n'existent qu'au moment de l'exécution, par exemple Player objets.En outre, l'hypothèse faite dans la syntaxe de classe Lua idiomatique est que déclarer une méthode sur une classe self sera toujours une instance de cette classe ; ce n'est pas une hypothèse que le moteur d'inférence de type peut faire.

Afin de prendre en charge l'inférence de type strict, le projet Plante utilise une solution qui diffère de la syntaxe de classe Lua idiomatique d'un certain nombre de façons, dont certaines peuvent sembler non intuitives :

  • La définition de self est dupliquée, à la fois dans la déclaration de type et dans le constructeur.Cela introduit une charge de maintenance, mais des avertissements seront affichés si les deux définitions tombent en désaccord les unes avec les autres.
  • Les méthodes de classe sont déclarées avec un point, donc self peut être explicitement déclaré du type ClassType.Les méthodes peuvent toujours être appelées avec une colonne comme prévu.

--!严格ement
local MyClass = {}
MyClass.__index = MyClass
export type ClassType = typeof(setmetatable(
{} :: {
property: number,
},
MyClass
))
function MyClass.new(property: number): ClassType
local self = {
property = property,
}
setmetatable(self, MyClass)
return self
end
function MyClass.addOne(self: ClassType)
self.property += 1
end
return MyClass

Lancer des types après les gardes logiques

Au moment de l'écriture, le type d'une valeur n'est pas restreint après une déclaration conditionnelle de garde.Par exemple, en suivant la garde ci-dessous, le type de optionalParameter n'est pas restreint à number .


--!严格ement
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
print(optionalParameter + 1)
end

Pour atténuer cela, de nouvelles variables sont créées après ces gardes avec leur type explicitement cast.


--!严格ement
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
local parameter = optionalParameter :: number
print(parameter + 1)
end

Traverser les hiérarchies de modèle de données

Dans certains cas, la base de code doit parcourir la hiérarchie du modèle de données d'un arbre d'objets créés au moment de l'temps d'exécution.Cela présente un défi intéressant pour la vérification du type.Au moment de l'écriture, il n'est pas possible de définir une hiérarchie de modèle de données générique comme taper.Par resultats, il y a des cas où les seules informations de type disponibles pour une structure de modèle de données sont le type de l'instance de niveau supérieur.

Une approche de ce défi consiste à lancer à any et ensuite à affiner. Par exemple :


local function enableVendor(vendor: Model)
local zonePart: BasePart = (vendor :: any).ZonePart
end

Le problème avec cette approche est qu'elle a un impact sur la lisibilité.Au lieu de cela, le projet utilise un module générique appelé getInstance pour parcourir les hiérarchies de modèle de données qui se traduisent en interne en any.


local function enableVendor(vendor: Model)
local zonePart: BasePart = getInstance(vendor, "ZonePart")
end

Au fur et à mesure que la compréhension du modèle de données de l'engine de type évolue, il est possible que des modèles comme celui-ci ne soient plus nécessaires.

Interface utilisateur

Plante inclut une variété d'interfaces utilisateur 2D complexes et simples.Cela inclut des éléments de notification non interactifs (HUD) tels que le compteur de pièces et des menus interactifs complexes comme la boutique.

Approche UI

Vous pouvez comparer de manière imprécise l'interface utilisateur Roblox à la DOM HTML, car c'est une hiérarchie d'objets qui décrivent ce que l'utilisateur devrait voir.Les approches pour créer et mettre à jour une interface utilisateur Roblox sont largement divisées en pratiques impératives et déclaratives .

ApprocheAvantages et inconvénients
Impératif

Dans l'approche impérative, l'interface utilisateur est traitée comme toute autre hiérarchie d'instance sur Roblox.La structure de l'interface utilisateur est créée avant l'exécution dans Studio et ajoutée au modèlisationde données, généralement directement dans StarterGui .Ensuite, à l'exécution, le code manipule des parties spécifiques de l'interface utilisateur pour refléter l'état que le créateur requiert.:

Cette approche comporte quelques avantages.Vous pouvez créer l'interface utilisateur à partir de zéro dans Studio et la stocker dans le modèlisationde données.C'est une expérience d'édition simple et visuelle qui peut accélérer la créationsd'interface utilisateur.Parce que le code d'interface utilisateur impératif ne se soucie que de ce qui doit être modifié, il facilite également l'implémentation de modifications simples de l'interface utilisateur.:

Un inconvénient notable est que, puisque les approches d'interface utilisateur impératives nécessitent que l'état soit implémenté manuellement sous forme de transformations, les représentations complexes de l'état peuvent devenir très difficiles à trouver et à débugger.Il est courant que des erreurs émergent lors du développement de code d'interface imposé, notamment lorsque l'état et l'interface deviennent désynchronisés en raison de plusieurs mises à jour interagissant dans un ordre inattendu.:

Un autre défi avec des approches imposées est que c'est plus difficile de décomposer l'interface utilisateur en composants significatifs qui peuvent être déclarés une fois et réutilisés.Puisque l'ensemble de l'arbre d'interface utilisateur est déclaré au moment de l'édition, des modèles communs peuvent se répéter dans plusieurs parties du modèlisationde données.

Déclaratif

Dans l'approche déclarative, l'état souhaité des instances d'interface est déclaré explicitement, et la mise en œuvre efficace de cet état est abstraite par des bibliothèques telles que Roact ou Fusion.:

L'avantage de cette approche est la mise en œuvre de l'état devient trivial et vous n'avez besoin que de décrire ce que vous voulez que votre interface utilisateur ressemble.Cela rend l'identification et la résolution des bugs beaucoup plus faciles.:

Le principal inconvénient est de devoir déclarer l'ensemble de l'arbre d'interface utilisateur en code.Les bibliothèques comme Roact et Fusion ont une syntaxe pour rendre cela plus facile, mais c'est toujours un processus long et une expérience d'édition moins intuitive lors de la composition de l'interface utilisateur.

Plante utilise une approche impérative sous la notion que montrer les transformations directement donne une vision plus efficace de la façon dont l'interface utilisateur est créée et manipulée sur Roblox.Cela ne serait pas possible avec une approche déclarative.Certaines structures et logiques d'interface utilisateur répétées sont également abstraites en composants réutilisables pour éviter un piège commun dans le design d'interface utilisateur impératif.

Architecture de haut niveau

Plant project UI architecture diagram

Couche et composants

Dans Plante, toutes les structures d'interface utilisateur sont soit un Layer ou un Component.

  • Layer est défini comme un groupe de niveau supérieur qui enveloppe les structures d'interface préfabriquées dans ReplicatedStorage .Une couche peut contenir un certain nombre de composants, ou elle peut encapsuler toute sa propre logique.Des exemples de couches sont le menu d'inventaire ou l'indicateur du nombre de pièces dans l'affichage en haut.
  • Component est un élément d'interface réutilisable.Lorsqu'un nouvel objet de composant est instancié, il clone un modèle préfabriqué à partir de ReplicatedStorage .Les composants peuvent eux-mêmes contenir d'autres composants.Des exemples de composants sont une classe de bouton générique ou la notion d'une liste d'éléments.

Afficher la manipulation

Un problème commun de gestion de l'interface utilisateur est la manipulation des vues.Ce projet a une gamme de menus et d'éléments HUD, dont certains écoutent l'entrée de l'utilisateur et dont une gestion soigneuse du moment où ils sont visibles ou activés est requise.

Plante aborde ce problème avec son système UIHandler qui gère quand une couche d'interface utilisateur doit ou ne doit pas être visible.Toutes les couches d'interface utilisateur dans le jeu sont catégorisées comme HUD ou Menu et leur visibilité est gérée par les règles suivantes :

  • L'état activé de Menu et HUD couches peut être basculé.
  • Les couches activées HUD ne sont affichées que si aucune couche Menu n'est activée.
  • Les couches activées Menu sont stockées en pile, et une seule couche Menu est visible à la fois.Lorsqu'une couche Menu est activée, elle est insérée en avant de la pile et est affichée.Lorsqu'une couche Menu est désactivée, elle est supprimée de la pile et la couche suivante activée Menu de la file d'attente est affichée.

Cette approche est intuitive car elle permet de naviguer dans les menus avec l'histoire.Si un menu est ouvert à partir d'un autre menu, la fermeture du nouveau menu montrera à nouveau le menu ancien.

Les singletons de couche d'interface utilisateur s'enregistrent eux-mêmes avec le gestionnaire d'interface utilisateur et sont fournis avec un signal qui se déclenche lorsque sa visibilité devrait changer.

En savoir plus

À partir de cette vue d'ensemble complète du projet Plante, vous pouvez vouloir explorer les guides suivants qui vont plus en profondeur sur les concepts et les sujets liés.

  • Modèle client-serveur — Un aperçu du modèle client-serveur dans Roblox.
  • Luau — Détails sur Luau , le langage de script créé par Roblox descendant de Lua 5.1 .
  • Événements et rappels à distance — Tout sur les événements et les rappels réseau à distance pour la communication à travers la frontière client-serveur.
  • UI — Détails sur les objets d'interface utilisateur et le design sur Roblox.