Tri par profondeur isométrique pour plates-formes mobiles

Ce que vous allez créer

Le tri en profondeur peut être expliqué en termes simples pour déterminer quel élément est le plus proche de la caméra et lequel est le plus éloigné, déterminant ainsi l'ordre dans lequel ils doivent être disposés pour donner la profondeur adéquate dans la scène..

Dans ce didacticiel, nous allons approfondir le tri en profondeur pour les niveaux isométriques lorsque nous essayons d'ajouter des plates-formes mobiles. Ce n'est pas un tutoriel pour débutant sur la théorie isométrique et ne concerne pas le code. L'objectif est de comprendre la logique et la théorie plutôt que de disséquer le code. L’un des outils de choix pour ce didacticiel est Unity. Par conséquent, le tri en profondeur change essentiellement la ordre de tri des sprites impliqués. Pour d’autres cadres, il peut s’agir d’un changement de l’ordre z ou de la séquence d’ordre du dessin.

Pour vous initier à la théorie isométrique, reportez-vous à cette série de didacticiels. Le code et la structure de la scène suivent mon précédent tutoriel sur l'isométrie. Veuillez vous y référer si vous trouvez que le tutoriel est difficile à suivre car je ne me concentrerai que sur la logique..

1. Niveaux sans mouvement

Si votre niveau isométrique ne comporte aucun élément en mouvement ou si quelques caractères le survolent, le tri en profondeur est simple. Dans de tels cas, les caractères occupant les carreaux isométriques seraient plus petits que les carreaux eux-mêmes et pourraient simplement utiliser le même ordre / profondeur de dessin que le carreau qu'ils occupent.. 

Appelons ces niveaux immobiles les niveaux statiques. Il y a quelques façons de tracer ces niveaux pour obtenir la profondeur appropriée. En règle générale, les données de niveau seront un tableau à deux dimensions où les lignes et les colonnes correspondront aux lignes et aux colonnes du niveau.. 

Considérez le niveau isométrique suivant avec seulement deux lignes et sept colonnes.

Les chiffres sur les carreaux indiquent leur ordre de tri ou la profondeur ou l’ordre z, c’est-à-dire l’ordre dans lequel ils doivent être dessinés. Dans cette méthode, nous dessinons toutes les colonnes de la première ligne, en commençant par la première colonne avec un ordre de tri de 1. 

Une fois que toutes les colonnes sont dessinées dans la première ligne, la colonne la plus proche de la caméra a un ordre de tri de 7, et nous passons à la rangée suivante. Ainsi, tout élément de la deuxième ligne aura une valeur plus élevée. ordre de tri que tout élément de la première rangée. 

C’est exactement comme cela que les carreaux doivent être disposés pour donner la profondeur correcte en tant qu’image-objet avec un ordre de tri se superposera à tout autre sprite avec un niveau inférieur ordre de tri.

Quant au code, il s’agit simplement de parcourir les lignes et les colonnes du tableau de niveaux et d’affecter ordre de tri séquentiellement dans un ordre croissant. Cela ne casserait pas, même si nous échangeons des lignes et des colonnes, comme on peut le voir dans l'image ci-dessous.

Ici, nous dessinons d'abord une colonne complète avant de passer à la ligne suivante. La perception de la profondeur reste intacte. La logique d’un niveau statique consiste donc à tracer une ligne complète ou une colonne complète, puis à passer à la suivante tout en affectant ordre de tri séquentiellement dans un ordre croissant.

Ajout de hauteur

Si nous considérons le niveau comme un bâtiment, nous dessinons actuellement le rez-de-chaussée. Si nous devons ajouter un nouvel étage à notre bâtiment, tout ce que nous avons à faire est d’attendre que nous dessinions tout le rez-de-chaussée en premier et suivions la même méthode pour le prochain étage.. 

Pour obtenir la profondeur appropriée, nous avons attendu que la rangée complète soit terminée avant de passer à la rangée suivante. De même, nous attendons que toutes les rangées soient terminées avant de passer à l'étage suivant. Donc, pour un niveau avec une seule rangée et deux étages, cela ressemblerait à l'image ci-dessous.

Essentiellement, toute tuile de l’étage supérieur aura un ordre de tri que n'importe quelle tuile à l'étage inférieur. Pour ce qui est du code d’ajout d’étages supérieurs, il suffit de compenser le y valeur des coordonnées de l'écran pour la tuile, en fonction de l'étage occupé.

float floorHeight = tileSize / 2.2f; float currentFloorHeight = floorHeight * floorLevel; // tmpPos = GetScreenPointFromLevelIndices (i, j); tmpPos.y + = currentFloorHeight; tile.transform.position = tmpPos;

le étageHauteur valeur indique la hauteur perçue de l’image de mosaïque de bloc isométrique, alors que niveau du sol indique quel étage la tuile occupe.

2. Déplacement de tuiles sur l’axe X

Le tri en profondeur au niveau isométrique statique n’était pas compliqué, non? Passons à autre chose, décidons de suivre la méthode de la première ligne, où nous affectons ordre de tri à la première rangée complètement puis passez à la suivante. Considérons notre première tuile ou plate-forme mobile qui se déplace sur un seul axe, l'axe x. 

Lorsque je dis que le mouvement est sur l'axe des x, vous devez comprendre que nous parlons du système de coordonnées cartésien et non du système de coordonnées isométrique. Considérons un niveau avec seulement un rez-de-chaussée de trois rangées et sept colonnes. Considérons également que la deuxième ligne ne comporte qu'une seule tuile, qui est notre tuile en mouvement. Le niveau ressemblera à l'image ci-dessous.

La tuile sombre est notre tuile en mouvement, et la ordre de tri il sera assigné sera 8 comme la première rangée a 7 tuiles. Si la tuile se déplace sur l'axe x cartésien, elle se déplacera le long de la tranchée entre les deux rangées. À tous les endroits qu’il peut occuper le long de ce chemin, les tuiles de la rangée 1 auront un moindre ordre de tri

De même, toutes les tuiles de la rangée 2 auront un ordre de tri, quelle que soit la position de la tuile sombre le long dudit chemin. Donc, comme nous suivons une première ligne de méthode d'affectation ordre de tri, nous n'avons rien à faire pour le mouvement sur l'axe des x. C'était facile.

3. Déplacement de tuiles sur l’axe Y

Des problèmes commencent à apparaître lorsque nous commençons à considérer l'axe des ordonnées. Considérons un niveau dans lequel notre tuile sombre se déplace le long d'une tranchée rectangulaire, comme indiqué ci-dessous. Vous pouvez voir la même chose dans le MovingSortingProblem Scène Unity dans la source.

En utilisant notre approche par rangée, nous pouvons fournir un ordre de tri pour notre tuile mobile basée sur la rangée qu’elle occupe actuellement. Quand la tuile est entre deux lignes, on lui attribue un ordre de tri en fonction de la ligne depuis laquelle il se déplace. Dans ce cas, il ne peut pas suivre la séquence ordre de tri dans la rangée dans laquelle il se déplace. Cela brise essentiellement notre approche de tri en profondeur.

Tri en blocs

Afin de résoudre ce problème, nous devons diviser notre niveau en différents blocs, parmi lesquels le bloc problème, qui casse sous notre première approche en rangée, et les autres blocs pouvant suivre la première approche sans rupture. Considérez l'image ci-dessous pour une meilleure compréhension.

Le bloc de tuiles 2x2 représenté par la zone bleue est notre bloc problème. Tous les autres blocs peuvent toujours suivre la première approche en rangée. Veuillez ne pas être dérouté par l'image, car elle indique un niveau qui est déjà correctement trié selon notre approche par blocs. Le bloc bleu est constitué des deux tuiles de colonnes dans les rangées entre lesquelles notre tuile sombre est actuellement en mouvement et les tuiles immédiatement à gauche de celles-ci.. 

Afin de résoudre le problème de la profondeur du bloc à problèmes, nous pouvons utiliser la méthode de la première colonne pour ce bloc uniquement. Donc, pour les blocs vert, rose et jaune, nous utilisons la première ligne, et pour le bloc bleu, nous utilisons l'approche de la première colonne. 

Notez que nous devons encore attribuer séquentiellement le ordre de tri. D'abord le bloc vert, puis le bloc rose à gauche, puis le bloc bleu, vient maintenant le bloc rose à droite et enfin le bloc jaune. Nous cassons l'ordre uniquement pour passer à la première approche de colonne alors que nous sommes au bloc bleu.

Alternativement, nous pouvons également considérer le bloc 2x2 situé à droite de la colonne de mosaïque en mouvement. (Ce qui est intéressant, c’est que vous n’avez même pas besoin de changer d’approche, car casser des blocs en soi a déjà résolu notre problème dans ce cas.) La solution est visible dans l’action BlockSort scène.

Cela se traduit par le code ci-dessous.

private void DepthSort () Vector2 movingTilePos = GetLevelIndicesFromScreenPoint (movingGO.transform.position); int blockColStart = (int) movingTilePos.y; int blockRowStart = (int) movingTilePos.x; int profondeur = 1; // trie les lignes avant bloc pour (int i = 0; i < blockRowStart; i++)  for (int j = 0; j < cols; j++)  depth=AssignDepth(i,j,depth);   //sort columns in same row before the block for (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = 0; j < blockColStart; j++)  depth=AssignDepth(i,j,depth);   //sort block for (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = blockColStart; j < blockColStart+2; j++)  if(movingTilePos.x==i&&movingTilePos.y==j) SpriteRenderer sr=movingGO.GetComponent(); sr.sortingOrder = profondeur; // attribue une nouvelle profondeur profondeur ++; // incrémente la profondeur else profondeur = AssignDepth (i, j, profondeur);  // trier les colonnes de la même ligne après le bloc pour (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = blockColStart+2; j < cols; j++)  depth=AssignDepth(i,j,depth);   //sort rows after block for (int i = blockRowStart+2; i < rows; i++)  for (int j = 0; j < cols; j++)  depth=AssignDepth(i,j,depth);   

4. Déplacement de tuiles sur l’axe Z

Un mouvement dans l'axe z est un faux mouvement à un niveau isométrique. Il s’agit essentiellement d’un mouvement sur l’axe y de l’écran. Pour un niveau isométrique à un étage, il n'y a rien de plus à faire pour ajouter du mouvement sur l'axe z si vous avez déjà utilisé la méthode de tri par blocs décrite ci-dessus. Vous pouvez voir cela en action dans le SingleLayerWave Scène Unity, où j'ai ajouté un mouvement d'onde supplémentaire sur l'axe z avec le mouvement de tranchée latérale.

Mouvement Z sur les niveaux à plusieurs étages

Ajouter un étage supplémentaire à votre niveau consiste simplement à décaler la coordonnée y de l'écran, comme expliqué précédemment. Si la tuile ne bouge pas sur l'axe z, il n'est pas nécessaire de faire quoi que ce soit de spécial pour le tri en profondeur. Nous pouvons bloquer le tri du rez-de-chaussée avec un mouvement puis appliquer le tri par rangée à chaque étage. Vous pouvez voir cela en action dans le BlockSortWithHeight Scène de l'unité.

Un problème de profondeur très similaire se pose lorsque la dalle commence à se déplacer entre les étages. Il ne peut satisfaire à l'ordre séquentiel d'un étage qu'en utilisant notre approche et romprait le tri en profondeur de l'autre étage. Nous devons étendre ou modifier notre tri en bloc en trois dimensions pour résoudre ce problème de profondeur avec les sols..

Le problème concernera essentiellement les deux étages entre lesquels la tuile est actuellement en mouvement. Pour tous les autres étages, nous pouvons nous en tenir à notre approche de tri actuelle. Les besoins spéciaux s’appliquent uniquement à ces deux étages, parmi lesquels nous pouvons d’abord déterminer l’étage inférieur comme suit: tileZOffset est la quantité de mouvement sur l'axe z pour notre tuile en mouvement.

float whichFloor = (tileZOffset / floorHeight); float lower = Mathf.Floor (quelFloor);

Cela signifie que inférieur et inférieur + 1 sont les sols qui nécessitent une approche particulière. L'astuce consiste à assigner ordre de tri pour ces deux étages ensemble, comme indiqué dans le code ci-dessous. Cela corrige la séquence de sorte que les problèmes de profondeur soient résolus.

if (floor == lower) // nous devons trier ensemble l'étage inférieur et l'étage juste au-dessus de celle-ci en profondeur = (floor * (rangées * colonnes)) + 1; int nextFloor = floor + 1; if (nextFloor> = totalFloors) nextFloor = floor; // trie les lignes avant bloc pour (int i = 0; i < blockRowStart; i++)  for (int j = 0; j < cols; j++)  depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor);   //sort columns in same row before the block for (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = 0; j < blockColStart; j++)  depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor);   //sort block for (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = blockColStart; j < blockColStart+2; j++)  if(movingTilePos.x==i&&movingTilePos.y==j) SpriteRenderer sr=movingGO.GetComponent(); sr.sortingOrder = profondeur; // attribue une nouvelle profondeur profondeur ++; // incrémente la profondeur else profondeur = AssignDepth (i, j, profondeur, plancher); profondeur = AssignDepth (i, j, profondeur, nextFloor);  // trier les colonnes de la même ligne après le bloc pour (int i = blockRowStart; i < blockRowStart+2; i++)  for (int j = blockColStart+2; j < cols; j++)  depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor);   //sort rows after block for (int i = blockRowStart+2; i < rows; i++)  for (int j = 0; j < cols; j++)  depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor);   

Essentiellement, nous considérons deux étages comme un seul étage et faisons une sorte de bloc à cet étage. Découvrez le code et l'action dans la scène BlockSortWithHeightMovement. Avec cette approche, notre tuile est maintenant libre de se déplacer sur l’un des deux axes sans casser la profondeur de la scène, comme indiqué ci-dessous..

Conclusion

L’idée de ce tutoriel était de clarifier la logique des méthodes de tri en profondeur, et j’espère que vous l’avez bien comprise. Il est évident que nous envisageons des niveaux relativement simples avec une seule tuile mobile. 

Il n'y a pas non plus de pentes, car l'inclusion de pentes aurait fait de ce didacticiel beaucoup plus long. Mais une fois que vous avez compris la logique de tri, vous pouvez essayer d'étendre la logique de pente bidimensionnelle à la vue isométrique..

L'unité a une économie active. Il existe de nombreux autres produits qui vous aident à construire votre projet. La nature de la plate-forme en fait également une excellente option à partir de laquelle vous pouvez améliorer vos compétences. Quel que soit le cas, vous pouvez voir ce que nous avons disponible sur le marché Envato.