Salut! Je suis Jamie Fristrom des Laboratoires Happion. Vous vous souvenez peut-être de moi dans des jeux tels que Die By The Sword, Spider-Man 2 et Schizoid… qui, sous une forme ou une autre, incluaient une corde. J'ai récemment travaillé sur un jeu appelé Energy Hook, récemment lancé sur Kickstarter, consacré à la corde. (De toute façon, il s'agit de votre faisceau de grappin à graviton.)
Je vais discuter de la manière dont j'aime mettre en œuvre un mécanisme de gameplay à corde pendante. Quand j'ai commencé à travailler sur Energy Hook, je faisais essentiellement tout avec mon propre code personnalisé. Je pense qu’il est possible d’utiliser simplement Unity et d’utiliser l’articulation configurable pour réaliser des tâches très similaires, mais à l’époque, elles n’étaient pas disponibles. De toute façon, je suis presque sûr que c'est le bon choix, car cela me permet de tout contrôler - et je peux le partager avec vous..
Les principes de base du swing comme je l’ai fait - en utilisant contraintes - sont en fait assez simples. (J'espère que vous n'êtes pas déçu quand vous voyez ce qu'il y a sous le capot.) Cela fonctionne de la même manière que vous fassiez un jeu en 2D ou en 3D, c'est simplement que les vecteurs sont différents, alors je commencerai par la 2D, puis discuter de quelques rides en allant à trois dimensions.
Cet article suppose également que vous utilisez un moteur de jeu tel que Unity qui peut effectuer une grande partie du travail, comme la diffusion de rayon contre la géométrie et l'orientation d'un personnage, avec de simples appels de fonctions. Si vous utilisez votre propre moteur, vous devrez peut-être faire le calcul vous-même.
Les simulations de jeu fonctionnent souvent de deux manières. La plupart des jeux à la troisième personne ont tout mis en conserve; animations et mouvements en boîte pour que tout soit parfait, les pieds du personnage ne glissent pas, directement du programme d'animation de l'animateur. L'alternative est une simulation beaucoup plus physique - vous simulez la physique: accélération, vitesse, gravité - beaucoup de jeux à la première personne le font, mais les jeux à la troisième personne ont tendance à l'éviter, car il est beaucoup plus facile d'avoir les pieds du personnage. slide et le matériel physique ne correspond pas à l'animation.
Si vous voulez faire une balançoire sans corde (par opposition à une balançoire en conserve, comme on le voit dans le tout premier Pitfall, ou les premiers jeux Spider-Man comme Neversoft sur PSX), une balançoire qui est en réalité un jeu physique. simulation et peut donc peut-être avoir la liberté et les nuances et le sentiment viscéral que la gravité et l’élan réels peuvent vous donner, alors vous voudrez le faire de la deuxième façon - ayez tout une simulation physique et évitez de mettre des choses en conserve qui tuent l'élan du personnage. Ensuite, tout va couler.
C'est comme ça que je fais les choses avec Energy Hook.
Il existe une tonne d'articles sur la simulation de la physique. En voici un avec une démo Flash intégrée. Vous pouvez effectuer l'intégration Euler ou Verlet, cela n'a pas d'importance. (Je ne vous apprendrai pas à propos de Euler contre Verlet ici, mais laissez-moi simplement dire que les concepts ne sont pas aussi effrayants qu'ils le paraissent.)
Supposons que nous fassions l'intégration osseuse d'os simple. Le temps de jeu de notre personnage pourrait ressembler à ceci, où l'accélération est déterminée par la gravité et la façon dont vous appuyez sur le manche:
avatar.velocity = avatar.velocity + avatar.acceleration * deltaT; avatar.position = avatar.position + avatar.velocity * deltaT;
(Remarque: c’est une approximation approximative - vous pouvez obtenir une meilleure approximation, moins dépendante de la vitesse de trame, avec avatar.position = avatar.position + (avatar.oldvelocity + avatar.velocity) * deltaT / 2.0f
, et vous pouvez obtenir une simulation proche de la perfection avec quelque chose comme ceci - mais vos joueurs ne le remarqueront probablement pas.)
Votre jeu a probablement un système permettant d’entrer en collision avec la géométrie du monde. Cela ressemble probablement à ceci:
Vecteur testPosition = avatar.position + avatar.velocity * deltaT; Intersection de vecteur if (RayCast (position, testPosition, intersection sur)) // nous avons traversé un mur, retirons le caractère en arrière //, en utilisant la normale du mur // avec un espace de 1 unité pour l'espace de respiration testPosition = intersection + intersection.normal;
Qu'advient-il de la vitesse de votre avatar quand ils frappent un obstacle? Cela n'a pas de sens pour votre avatar de conserver la même vitesse à travers le mur. Certains jeux peuvent vous rebondir, en utilisant la normale de l'endroit où vous avez intersecté pour refléter votre vitesse; d'autres jeux pourraient vous laisser glisser le long du mur; d'autres seront quelque part entre les deux. Regardons le code pour glisser le long d'un mur:
avatar.velocity = (testPosition - avatar.position) / deltaT; avatar.position = testPosition;
(Si vous effectuez une intégration Verlet, où chaque image détermine déjà la vitesse simplement en regardant les données de position précédentes, cette étape est déjà faite pour vous.)
En outre, les jeux vidéo étant les choses les plus compliquées qu'ils soient, vous constaterez probablement souvent que la position de votre personnage se modifie soudainement d'une image à l'autre dans certains cas. Lorsque cela se produit, leur vitesse va à travers le toit. Ma solution à cela est simplement un hack: vérifiez si leur vitesse devient trop extrême et corrigez-la si c'est le cas..
Que fait ce code lorsque vous frappez un mur de biais? La première image modifie radicalement votre vélocité lorsque vous frappez le mur, mais vous pousse toujours à travers le mur. La prochaine image, votre avatar est à nouveau mis à jour dans le mur, puis repoussé à nouveau, mais maintenant la vitesse correspond à la nouvelle position de l'avatar, glissé le long du mur, moins son ancienne position, contre le mur, de sorte qu'il est parallèle au mur..
C’est une énorme simplification excessive de ce qui se passe dans le monde réel quand un objet se heurte à un autre, mais la plupart de vos joueurs ne le remarqueront pas et ne s'en soucieront pas..
À ce stade, cependant, nous avons réussi à contraindre la position et la vitesse de notre avatar avec les murs et les sols de notre jeu. Alors maintenant nous sommes prêts.
Alors maintenant, imaginez que votre avatar est déjà attaché par une corde virtuelle à un point virtuel. En ce qui nous concerne, on peut simplement considérer qu’il s’agit d’un mur invisible circulaire ou sphérique. Nous pouvons tester la collision en vérifiant si vous vous êtes trop éloigné du centre du cercle et en ramenant l'avatar.
if (amITethered) if (testPosition - tetherPoint) .Length ()> tetherLength) // nous avons dépassé la fin de notre corde // ramène l'avatar en arrière. testPosition = (testPosition - tetherPoint) .Normalized () * tetherLength;
Maintenant, le même réglage de vitesse qui nous a fait glisser le long des murs nous fera également glisser le long de l'intérieur de ce cercle ou de cette sphère virtuelle.
À ce stade, vous avez un jeu oscillant. Mais il y aura probablement quelques petites choses à ce sujet qui gêneront vos joueurs et c'est là qu'un peu de piratage informatique peut améliorer les choses..
En fonction de votre jeu et de la supposée simulation d'une longueur de corde, d'une bande élastique ou d'une poutre à grappin, vous pouvez avoir différentes approches du mou et de l'élasticité. Vous pouvez simuler beaucoup de choses en ajustant la longueur de l'attache
. Si vous souhaitez vous détendre sur votre toile élastique ou votre poutre de grappin, vous pouvez raccourcir la longueur de l'attache
à mesure que le joueur se rapproche du point d'attache:
tetherLength = (avatar.position - tetherPoint) .Length ();
Mais si c'est une corde non élastique, vous quitteriez le longueur de l'attache
intacte.
Pour le printemps, vous pouvez avoir un longueur désirée
c'est fixe et un currentLength
qui tente continuellement d'approcher le longueur désirée
- cela sera également utile pour notre prochaine étape:
Que se passe-t-il si votre avatar commence dans un endroit bas et tente de se balancer? Il est évident qu'ils n'iront pas très loin. Une solution rapide consiste à vérifier à quelle hauteur le point sur lequel ils veulent se déplacer doit être au-dessus du sol et à raccourcir la longueur de leur attache pour qu'ils nettoient le sol..
Cependant, vous ne pouvez pas simplement le raccourcir d’un cadre, car ils vont soudainement se projeter dans les airs. longueur désirée
c'est assez court pour ne pas toucher le sol et un currentLength
qui approche rapidement longueur désirée
vous obtiendrez l'autorisation que vous voulez.
Si votre avatar est une figure humaniste, il n’a pas de sens de paraître constamment parfaitement vertical lorsqu’il se balance. En les orientant de manière à ce qu'ils aient l'air d'être suspendus à la corde - ils sont donc à l'envers s'ils font une boucle, par exemple - pourraient ressembler à ceci dans Unity:
Vector myUp = (avatar.position - tetherPoint); avatar.rotation = Quaternion.LookRotation (avatar.rotation.forward, myUp);
Cela laissera l’avatar basculer en arrière. Vous pouvez également utiliser la vélocité de l'avatar pour l'attaquant (c'est ce que je fais) - ou les laisser tourner follement…
Dans le monde réel, des cordes enveloppent des objets. Un moyen rapide de simuler cela dans votre code est de lancer un rayon le long de la corde virtuelle de chaque image, et si elle heurte quelque chose, créez un nouveau point de fixation à l’intersection de celle-ci. Cela n’aura pas l’air si l’avatar bascule ensuite sur une corde non collante, mais convient également pour une bande collante, une langue ou une poutre à grappin.
En peaufinant la façon dont vos cordes enroulées peuvent avoir un impact important sur le plaisir. S'enrouler brusquement autour d'un affleurement peut prendre le joueur par surprise et le frustrer. Nous avions une solution en trois étapes dans Spider-Man 2: si vous étiez trop près de l’affleurement, le Web se briserait; si vous étiez à mi-distance, le Web s'enroulerait; et si vous étiez loin, le web passerait par.
Le plus difficile pour amener ce mécanicien 2D en 3D est de considérer l'interface du joueur - comment il choisit des points dans le monde. Différents jeux utilisent différentes méthodes pour choisir un tel point. Ratchet & Clank a des points fixes dans le monde que vous pouvez attaquer; avec le mod Quake Grappling-hook et Bionic Commando: Réarmé, dirigez la caméra vers ce que vous souhaitez attacher; Spider-Man 2 et Energy Hook diffusent des rayons par rapport au personnage et à l'endroit où ils intersectent une géométrie physique constituant le point d'attache..
Presque toutes ces méthodes impliquent la diffusion de rayons en fonction de la géométrie physique du monde, que ce soit le long de la ligne de la caméra ou du personnage au point du clic de la souris. L'intersection du rayon de diffusion détermine votre nouveau point d'attache..
Par exemple, voici un raycast ressemblant à une souris qui pourrait être bon pour un jeu à la première personne:
RaycastHit wallData; if (Physics.Raycast (camera.position, camera.forward, out wallData, maximumTetherLength)) amITethered = true; tetherPoint = wallData.point; tetherLength = Vector3.Distance (wallData.point, avatar.position);
Se cogner contre des murs, etc., a également tendance à se produire beaucoup plus souvent dans un jeu 3D que dans un jeu en 2D, en particulier lorsque ce sont les murs auxquels vous vous attachez. Il y a une variété de choses que vous pouvez faire pour rendre cela moins ennuyeux.
Allez-y et faites vos propres jeux de swing, et laissez-moi savoir ce que vous venez avec! Je ne peux jamais avoir assez de jeux de swing.
J'espère que vous avez trouvé cet article utile. Si tel est le cas, soutenez Energy Kookstarter ou votez pour Steam Greenlight. Merci!