Les marqueurs d'objectifs sont utilisés dans de nombreux jeux pour guider le joueur vers l'objectif ou le point d'intérêt suivant. Dans ce tutoriel, vous allez apprendre à créer un marqueur d'objectif réutilisable à l'aide de l'appareil d'indicateur de carte et de Verse.
Fonctionnalités du langage Verse utilisées
struct : vous pouvez regrouper des variables de différents types dans une structure.
Méthode d'extension : type spécial de fonction qui agit comme un membre d'une classe ou d'un type existant, mais qui ne nécessite pas la création d'un nouveau type ou d'une sous-classe. Dans ce guide, vous allez créer une méthode d'extension pour la structure.
argument nommé : argument transmis à un appel de fonction avec son paramètre spécifié.
API Verse utilisées
API creative_prop : l’API
creative_propfournit des méthodes pour le déplacement des accessoires.Propriétés modifiables : plusieurs propriétés sont utilisées simultanément pour référencer les appareils et mettre à jour les valeurs variables pour des tests rapides.
Instructions
Procédez comme suit pour apprendre à configurer un appareil Marqueur d'objectif unique pouvant se déplacer vers plusieurs objectifs ou points d'intérêt. Les scripts complets sont inclus à la fin de ce guide à titre de référence.
Configurer le niveau
Dans cet exemple, nous utiliserons les accessoires et appareils suivants.
1 accessoire de bâtiment : accessoire qui servira à déplacer l'appareil d'indicateur de carte.
1 appareil d'indicateur de carte : appareil qui affichera des marqueurs personnalisés sur la minicarte et la carte de vue d'ensemble.
1 appareil Point d'apparition de joueur : ajoutez-le à proximité de l'accessoire pour que le joueur apparaisse à côté de lui.
Utilisation de l'API Prop
La première étape pour changer un appareil de place avec Verse consiste à déplacer un accessoire avec l'API Accessoire. Procédez comme suit pour déplacer un accessoire dans votre niveau.
Créez un nouvel appareil Verse nommé objective_coordinator_device.
Sous les expressions
usingpar défaut en haut du fichier Verse, ajoutez une expressionusingpour le module SpatialMath. Ce module contient le code auquel vous ferez référence pour déplacer les accessoires.Verseusing { /UnrealEngine.com/Temporary/SpatialMath }Ajouter deux propriétés modifiables :
Une constante
creative_propnomméeRootProppour stocker une référence à l'objet en mouvement.Une constante
transformnomméeDestinationpour stocker l'emplacement vers lequel l'objet se déplace.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): @editable RootProp<public> : creative_prop = creative_prop{} @editable Destination<public> : transform = transform{}
Si vous exécutez ce code et faites glisser votre appareil objective_coordinator_device dans votre niveau, les deux propriétés s'affichent dans le panneau Détails.
C'est en fait la méthode
TeleportTo[]qui déplace l'objet. Appelez-la dans une expression if et utilisez des crochets au lieu de parenthèses, carTeleportTo[]est une expression faillible.ifcrée un contexte d'échec.Verseif(RootProp.TeleportTo[Destination.Translation, Destination.Rotation]): Print("Prop move successful") else: Print("Prop move failed")Les arguments de
TeleportTo[]sont Translation et Rotation. Ils proviennent tous deux de votre propriété Destination.Revenez à l'éditeur, puis faites glisser un accessoire depuis Fortnite > Galeries > Accessoires dans le navigateur de contenu. Dans ce guide, nous utilisons l'accessoire Bouée côtière 02B, mais tous les accessoires qui se trouvent dans le dossier Accessoires doivent normalement fonctionner.
Sélectionnez votre coordinateur d'objectif dans l'organiseur. Dans le panneau Détails, définissez RootProp sur votre accessoire. Dans cet exemple, RootProp est défini sur Bouée côtière 02B.
Dans le panneau Détails, développez Destination. Dans la mesure où la propriété Destination est de type
transform, elle est composée d'une échelle, d'une rotation et d'une translation. Pour déplacer l'accessoire, il suffit de modifier la translation ; par conséquent, développez-la. Définissez le champ qui se termine par X sur 5 000,0.Pour tester votre code, nous vous conseillons d'appliquer des modifications importantes aux valeurs afin que les effets soient évidents. Avec de petites modifications, vous ne saurez pas si votre code s'exécute comme prévu.
Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } using { /UnrealEngine.com/Temporary/SpatialMath } objective_coordinator_device<public> := class<concrete>(creative_device): @editable RootProp<public> : creative_prop = creative_prop{} # Where the marker will be moved toCliquez sur Verse, sur Générer le code Verse, puis sur Lancer la session. Enfin, cliquez sur Lancer le jeu. Vous devriez voir votre accessoire se déplacer.
Parent et structures
Vous disposez maintenant d’un accessoire qui se déplace dans votre niveau, mais le véritable objectif est de déplacer un indicateur de carte afin que les joueurs puissent l'utiliser comme point de repère. Procédez comme suit pour ajouter un accessoire de bâtiment et un indicateur de carte à votre niveau et les fixer à l’accessoire de bâtiment.
Faites un clic droit dans le navigateur de contenu pour ouvrir le menu contextuel.
Sélectionnez Classe de blueprint dans le menu contextuel.
Dans la fenêtre Choisir une classe parente, cliquez sur Accessoire de bâtiment.
Une nouvelle classe de blueprint apparaît dans votre navigateur de contenu. Renommez-la BuildingProp.
Faites glisser l'accessoire de bâtiment dans votre niveau. Étant donné que cet accessoire n'a pas de maillage, vous ne voyez que son gadget de transformation.
Dans l'organiseur, faites glisser l'appareil d'indicateur de carte sur l'accessoire de bâtiment. L'accessoire de bâtiment devient alors le parent de l'indicateur de carte. Ainsi, lorsque l'accessoire de bâtiment se déplace, l'indicateur de carte se déplace avec lui.
Vous avez appris à créer un appareil à l'aide de Verse, mais pouvez également créer des fichiers Verse qui ne disposent pas de leurs propres appareils.
Créez un nouveau fichier Verse et nommez-le objective_marker. Ce fichier ne crée pas d'appareil. Il contient la définition d'une
structurequi sera exposée à l'appareil Verse que vous avez créé plus tôt.Commencez par déclarer une
structurenommée objective_marker. Celle-ci est constituée de deux membres :RootPropetMapIndicator. Tous deux doivent avoir le spécificateur@editable.Verseobjective_marker<public> := struct<concrete>: @editable RootProp<public> : creative_prop = creative_prop{} @editable MapIndicator<public> : map_indicator_device = map_indicator_device{}
Méthodes d'extension et arguments nommés
Déclarez une seule méthode, MoveMarker, qui déplacera le membre RootProp et l'appareil d'indicateur de carte qui lui est associé. Cette méthode introduit deux fonctionnalités de langage : les méthodes d'extension et les arguments nommés.
(Marker : objective_marker).MoveMarker<public>(Transform : transform, ?OverTime : float)<suspends> : void =Méthodes d'extension : vous ajoutez la méthode
MoveMarker()à la structureobjective_marker. Pour déclarer une méthode d'extension, mettez un identificateur et un type séparés par deux points entre parenthèses. En l'occurrence :(Marker : objective_marker).Arguments nommés : le second argument
?OverTimeutilise le caractère?pour indiquer qu'il doit être nommé dans l'appel à la fonctionMoveMarker. Cela permet à tout développeur lisant ou écrivant un appel àMoveMarkerde comprendre ce que fait l'argumentfloat.
MoveMarker() appelle l'une des deux méthodes de l'API Prop : TeleportTo[], que vous avez utilisée plus tôt, ou MoveTo(). Créez un bloc if..else pour vérifier si le paramètre OverTime est supérieur à 0,0. Si c'est le cas, appelez MoveTo(). Cela permet à votre objectif de se déplacer vers son prochain emplacement pendant la période que vous aurez spécifiée, au lieu de se téléporter instantanément.
(Marker : objective_marker).MoveMarker<public>(Transform : transform, ?OverTime : float)<suspends> : void =
if (OverTime > 0.0):
Marker.RootProp.MoveTo(Transform.Translation, Transform.Rotation, OverTime)
else:
if:
Marker.RootProp.TeleportTo[Transform.Translation, Transform.Rotation]Si vous compilez le code maintenant, il doit réussir, mais le dossier CreativeDevices du navigateur de contenu ne doit pas contenir de nouvel appareil. Cela est dû au fait que objective_marker est une structure, et non une classe qui hérite de creative_device.
Mettre à jour le coordinateur d'objectif
Maintenant que vous disposez d'un nouveau type à référencer, vous devez mettre à jour l'appareil objective_coordinator_device pour le référencer.
Supprimez la propriété
RootPropet remplacez-la par une propriété nomméePickupMarkerdu typeobjective_marker. Il s'agit du type que vous créez.Dans la mesure où
MoveMarker()nécessite un argument de typefloat, créez-le comme propriété modifiable nomméeMoveTime.Supprimez l'appel à
TeleportTo[]. À la place, appelez la méthodeMoveMarker()que vous avez créée pourobjective_marker. Celle-ci nécessite l'argument nommé?OverTime.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): @editable PickupMarker<public> : objective_marker = objective_marker{} # Where the marker will be moved to @editable Destination<public> : transform = transform{} # How much time the marker should take to reach its new location
Compilez ce code et vérifiez les détails du coordinateur d’objectif. Vous devriez voir les propriétés PickupMarker et MoveTime, et la propriété PickupMarker doit contenir RootProp et MapIndicator.
Définissez le champ RootProp sur BuildingProp, et le champ MapIndicator sur Appareil d'indicateur de carte.
Compilez votre code et cliquez sur Lancer la session. Vous devriez voir un marqueur sur votre minicarte qui se déplace peu de temps après le début de votre partie. Testez-le en définissant
MoveTimesur différentes valeurs, y compris0,0. Réfléchissez au mouvement qui conviendrait le mieux aux différents scénarios.
GetPlayers() et ActivateObjectivePulse()
Il existe un moyen de donner un petit coup de pouce à vos joueurs pour atteindre leur objectif suivant. Il s'agit d'une impulsion d'objectif qui, lorsqu'elle est active, affiche une ligne en pointillé qui se déplace du joueur vers l'indicateur de carte. Procédez comme suit pour ajouter une impulsion d'objectif à votre coordinateur d'objectif.
La méthode dont vous avez besoin pour activer l'impulsion d'objectif est appelée ActivateObjectivePulse() et nécessite un argument de type agent. Commencez par créer la méthode pour obtenir l'instance d'agent représentant votre personnage joueur.
Déclarez une fonction appelée
FindPlayer()en la définissant sur<private>, avec une valeur de retour devoid.Obtenez une matrice de tous les joueurs de votre niveau avec
Self.GetPlayspace().GetPlayers(). Enregistrez la matrice dans une variable appeléeAllPlayers.VerseFindPlayer<private>() : void = AllPlayers := Self.GetPlayspace().GetPlayers()Pour obtenir la référence au seul et unique joueur de votre niveau, affectez le premier élément de la matrice à sa propre variable. L'accès à une matrice étant une expression faillible, placez-la dans une expression
if.Verseif (FirstPlayer := AllPlayers[0]):Étant donné que l'affectation de votre
joueurà une variable peut échouer, vous souhaitez utiliser une variable de type option lorsque vous référencez le joueur dans votre code. Déclarez une variable facultative?player. Elle doit aller de pair avec les autres variables du membre.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): var PlayerOpt<private> : ?player = false @editable PickupMarker<public> : objective_marker = objective_marker{} # Where the marker will be moved to @editable Destination<public> : transform = transform{}Définissez votre nouvelle variable et créez un bloc
elseavec une expressionPrint()qui vous indique si un joueur est introuvable. Votre fonctionFindPlayer()est maintenant terminée.VerseFindPlayer<private>() : void = # Since this is a single player experience, the first player [0] # should be the only one available. AllPlayers := Self.GetPlayspace().GetPlayers() if (FirstPlayer := AllPlayers[0]): set PlayerOpt = option{FirstPlayer} Print("Player found")
Revenez à la fonction OnBegin() pour effectuer deux autres modifications :
Appelez votre fonction
FindPlayer().VerseOnBegin<override>()<suspends> : void = FindPlayer()Après l'appel à
MoveMarker(), utilisez une autre expressionifpour définir votre variable de joueur facultative sur une nouvelle variable, et transmettez-la en tant qu'argument àPickupMarker.MapIndicator.ActivateObjectivePulse()Verseif (FoundPlayer := PlayerOpt?): PickupMarker.MapIndicator.ActivateObjectivePulse(FoundPlayer)
Si vous exécutez votre code maintenant, l'impulsion d'objectif doit pointer de votre personnage vers l'emplacement du marqueur d'objectif dans le niveau.
Scripts complets
Objective_marker.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Devices/CreativeAnimation }
objective_marker<public> := struct<concrete>:
# The prop that will be moved
@editable
RootProp<public> : creative_prop = creative_prop{}
Objective_coordinator_device.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /UnrealEngine.com/Temporary/SpatialMath }
objective_coordinator_device<public> := class<concrete>(creative_device):
var PlayerOpt<private> : ?player = false
@editable
À vous de jouer
Gardez à l'esprit que le code de mouvement que vous avez écrit ici fonctionne pour n'importe quel accessoire. Si vous pouvez faire d'un accessoire mobile le parent d'un appareil, cet appareil se déplace avec lui. Essayez de déplacer d'autres accessoires et appareils, et voyez si vous pourriez les utiliser dans d'autres jeux.
Étapes suivantes
Si vous utilisez ce guide pour créer le jeu de collecte/livraison, votre prochaine étape est d'apprendre à créer la fonction Compte à rebours.