Comment puis-je créer un terrain 3D «tombant» comme Animal Crossing?

15

Animal Crossing a une façon unique de faire défiler la carte du monde: lorsque le personnage descend, le monde tourne autour et au sommet, comme s'il était collé à un tube en carton:

Animal Crossing est le monde des cylindres

Cette vidéo montre comment il se déplace.

Comment puis-je créer cet effet?

Chris
la source
1
Cela ne ressemble pas à un effet pour moi, cela ressemble à un monde 3D très simple que la caméra ne fait que suivre.
James
Le piratage du jeu peut produire un problème de collision qui vous permet de marcher dans l'océan où le monde se termine. Vous pouvez voir des morceaux du monde rendus "recourbés" dans le vide au-delà du bord du monde. Vidéo ici .
Anko

Réponses:

6

J'expérimentais un peu après avoir joué à Deathspank, ce qui a un effet similaire. Bien que je ne l'ai jamais suffisamment exploré pour voir s'il peut être réglé pour fonctionner très bien, une possibilité consiste à simplement modifier les éléments de votre vertex shader en fonction de la profondeur. Une fonction mappant cos (profondeur) à une modification de l'axe Y fonctionne. Vous pouvez l'ajuster de telle sorte que le monde tombe non seulement au loin, mais aussi s'il est plus proche que la profondeur, ce qui rend le monde particulièrement rond. Vous pouvez faire de même pour la valeur de l'axe X pour la rendre plus sphérique. Je ne sais pas si c'est ainsi que ces jeux le font réellement; mes expériences ont donné des résultats insatisfaisants mais je n'ai pas beaucoup joué avec les ratios, donc cela a peut-être été aussi simple que de changer le taux de chute pour le rendre meilleur.

Sean Middleditch
la source
+1 parce que c'est ainsi que je procéderais. Cependant, vous voudrez peut-être clarifier ce que vous entendez par «profondeur». Cela peut être la distance de la caméra ou la distance du personnage. Je pense qu'il serait bon d'expérimenter avec les deux.
DaleyPaley
Désolé, je suis en retard à la fête - comme 6 ans de retard - mais dans le cas AC, la `` profondeur '' est calculée en fonction de la distance de la caméra ... mais comme la position de la caméra est basée sur la position du personnage, tout est en quelque sorte connecté.
lvictorino
5

On dirait qu'il suffit de prendre un "monde plat" et de cartographier des coordonnées cylindriques . Enveloppant essentiellement le monde sur un cylindre. J'ai fait quelque chose de similaire avec un monde plat, mais je l'ai enveloppé dans une sphère:

entrez la description de l'image ici entrez la description de l'image ici

La façon dont je l'ai fait pour une sphère est similaire à la façon dont vous le feriez pour un cylindre. Choisissez un rayon approprié (ρ ou "rho" en coordonnées cylindriques) pour votre monde. Pour chaque sommet, prenez les coordonnées XZ de votre monde (en supposant que Y est la hauteur), puis convertissez-vous en coordonnées cylindriques en utilisant le XZ et le rayon plus Y. Si vous n'ajoutez pas le Y, vous obtiendrez un cylindre plat. Puis reconvertissez les coordonnées cartésiennes pour dessiner dans le jeu.

MichaelHouse
la source
3
Une autre chose à mentionner, la dimension Y du monde dans Animal Crossing est beaucoup plus grande que la circonférence du cylindre (juste en le regardant, car la ligne d'horizon est très proche). Par conséquent, une partie de la carte du monde est recadrée uniquement dans les zones les plus proches du personnage et cette zone recadrée est enroulée autour de tout le cylindre. Cela revient à recadrer une carte 2D basée sur des tuiles uniquement pour les parties visibles.
ChrisC
Excellent point. J'imagine que cela pourrait également être utilisé pour garder l'empreinte mémoire petite en chargeant / déchargeant le monde selon les besoins.
MichaelHouse
5

Vous voulez passer d'un monde planaire à un monde cylindrique.

Une rotation autour de l'axe x (en coordonnées homogènes) ressemble à ceci:

     | 1   0   0   0 |
Rx = | 0  ca  -sa  0 |
     | 0  sa   ca  0 |
     | 0   0    0  1 |

Où:

ca = cos(angle) and sa = sin(angle)

Pour calculer l'angle, regardez l'image. Le pi / 2 s'annule et vous vous retrouvez avec:

angle = offset_from_character.z - radius

Regardez aussi l'image. L'angle du point projeté dépend de la distance horizontale du personnage, la distance de la sphère dépend de la verticale.

new_position = character_position - vec3(0,radius,0) + Rx * vec3(0,radius+_old_position.y,0)

assurez-vous de supprimer les choses qui se trouvent à l'horizon, sinon le monde entier s'enroulera.

Avertissement: je n'ai pas testé cela et je ne suis pas un expert en mathématiques, mais la réponse est quelque chose comme ça. Quelqu'un, s'il vous plaît, corrigez-moi si je me trompe.

monde sphérique

DaleyPaley
la source