vendredi 19 octobre 2018

[UNITY3D] Sauvegarde/Chargement des personnages + recherche de chemin plus intelligente

Hé salut ça faisait longtemps!
Et non le projet n'est PAS oublié, simplement, soyons honnête, j'ai passé plus d'un mois en vacances sans y toucher, donc le défi de 50 jours sans s'arrêter il est LEGEREMENT raté. Du coup je me fais plus chier à bosser dessus tous les jours, surtout que j'ai pas spécialement le temps pour en plus. Par contre, je bosse dessus dès que je peux, et je m'y mets au moins une heure à chaque fois, ça je le garde pasque bon ça je peux le faire. Et puis aussi, je vais écrire un article quand ce sera vraiment utile et qu'il y aura quelque chose à dire, pas juste: "hé j'ai passé deux heures a faire des mises à jour du coup j'ai rien fait en vrai lol tu l'aimes la carotte ou pas?"


La carotte

Enfin maintenant cette introduction passée, voici venu le temps de vous faire part des dernières avancées. Et bon, ben autant vous dire que je suis plutôt content de ce que j'ai pu ajouter récemment.
Comme vous l'avez vu dans le titre, les personnages sont maintenant sauvegardés et chargés proprement. Et ça, c'est top. Mais c'était pas si facile que ça, et c'etait un peu le truc qui me rebutait et que j'ai repoussé peut être un peu trop longtemps avant de finalement m'y pencher. Pourquoi c'était difficile, allez vous me dire? Et je suis content que cette question soit posée, car c'est exactement ce à quoi je comptais répondre. Le hasard du monologue de blog fait bien les choses quand même.

Comme expliqué précédemment, nous avons trois listes: la liste des humains, celle des humains sans maison, et celle des humains qui ont une maison. Quand une maison est posée, 5 humains y sont assignés et se dirigent vers cette maison. Ils sont ajoutés alors a la liste des humains et a celle des humains sans maison. Une fois arrivés a leur destination, ils sont enlevés de la liste des humains sans maison et sont rajoutés a celle des humains avec maison.

Jusque là rien de bien difficile. Mais pour plus tard, j'ai pour intention de faire en sorte que, en cliquant sur une maison, on puisse voir tous les humains qui y sont assignés. Donc pour cela, chaque maison possède elle aussi une liste d'humains. Pour simplifier, regardez le schéma suivant:


Schéma simplifié

Un humain possède une maison comme cible, et une maison possède une list d'humains comme habitants. Et là, pour sauvegarder, ça coince. Pourquoi? Hé bien simplement parce que le mecanisme de sérialization se contente de parcourir chaque objet et de le stocker tel quel. Ce qui veut dire que si on stocke un humain, il va donc stocker le champ "target" complet, donc une maison entière. Or la maison, elle, possède une liste d'humains. Donc en stockant la maison il va stocker tous les humains que la maison contient. Et donc pour chaque humain, il va restocker la maison (puisque pour chaque humain habitant, Target sera toujours cette maison). Et donc il va restocker la liste d'habitants. Et ainsi de suite. On est ici rentré dans une boucle infinie d'appel, où tout va etre stocké un nombre infini de fois. Et ça, ben on veut pas.

Alors heureusement, Unity est assez intelligent pour repérer ce genre de cas et s'arreter de stocker a partir d'un certain palier. On evite ainsi de faire planter le programme et aussi d'avoir un fichier de sauvegarde de 1200223454 To pour seulement trois cubes. Mais ça ne résout en rien le problème en fait. Heureusement, pour ça il existe une méthode assez simple, qui est de générer un identifiant unique a chaque humain et maison, et de stocker ces identifiants plutôt que les objets complets. Ainsi on évite les boucles infinies, on ne stocke chaque objet qu'une fois et une seule. Le schéma ressemble a ceci à la fin:

Schéma simplifié corrigé

Pour information, cette méthode d'identifiant unique est utilisée assez fréquemment dans le monde de l'informatique, notamment dans les systèmes de base de données. En effet ce système permet de récupérer rapidement un élément dans un grand ensemble, plutôt que d'avoir a parcourir manuellement tous les éléments un à un pour trouver le bon.
Et le chargement se fait ensuite tout seul, il n'y a plus qu'a récupérer les positions des objets, et dire a chaque humain où se diriger.


La seconde chose sur laquelle j'ai travaillé est le déplacement des humains. Avant, ils se contentaient de foncer en ligne droite vers la maison, en ignorant tout sur leur passage. Maintenant, ils éviterons arbres et autres maisons, et privilégieront la route s'ils en trouvent une dans leur direction. Pour ce faire j'ai simplement réadapté l'algorithme de recherche de chemin qu'on avait mis en place pour créer la route. J'ai juste eu a faire en sorte d'ignorer les arbres et les maisons, et de donner un cout moins élevé aux routes qu'aux morceaux d'herbes. Ainsi, voici ce que ça donne:



Du coup voilà, nos humains commencent à être un poile moins bêtes, et ça c'est cool. Prochaine étape, leur donner un endroit où travailler. Je pense. Je suis pas sûr.

En tout cas, c'en est fini pour cet update, j'espere que ça vous aura plus. N'hésitez pas à me dire ce que vous en pensez, si c'est pas trop technique aussi pasque je me pose toujours la question. Ou au contraire si ça ne l'est pas assez dites le aussi. Et en tout cas merci pour votre attention, et a très vite pour d'autres aventures chocolatéss.

samedi 29 septembre 2018

[Unity3D][Jour 17] Des gens

Salut les blogouzes ça roule?

Aujourd'hui j'ai pas chomé, j'ai bien avancé sur le jeu malgré une envie proche de zéro et un mal de crâne des enfers. Enfin c'est pas ce qui vous intéresse, vous ce que vous voulez c'est en savoir plus sur le jeu, parce que hein voilà bon bref ok j'arrête.

La nouveauté du jour, c'est la gestion des ressources. Enfin d'une ressource en particulier: les gens. En gros, j'ai créé un nouveau préfab que j'ai appelé "human", qui est juste un cylindre bleu (z'avez jamais vu des humains comme ça?). Lorsqu'il est créé a l'écran, on va lui assigner deux choses: une vitesse de déplacement, et une cible. Et son rôle, et bien ce sera simplement d'avancer vers la cible à sa vitesse jusqu'a l'atteindre.

Un humain




Alors oui, ça prend deux secondes à expliquer, mais en vrai, ça a pris plus d'une heure à mettre en place, entre le fait que je savais pas comment ça marchait sous Unity, et le fait de trouver une architecture de code pas trop dégueulasse et réutilisable, ça prend du temps.

Mais bon, maintenant que j'ai ça, on peut commencer à faire spawner des humains ! Et comment on fait ça? Ici j'ai fait quelque chose de très simple pour commencer, j'ai arbitrairement décidé qu'une maison pouvait contenir 5 habitants, et du coup, chaque fois qu'une nouvelle maison est créée, on crée aussi 5 humains, à qui on va donner pour cible cette maison. Et puis voilà quoi. Pour mieux comprendre l'idée, regardez le gif qui suit:


Et voilà le travail! Bon alors, ils foncent tout droit meme au travers des arbres, ils viennent tous du meme coin, mais l'important c'est que ça marche, il ne faut pas oublier que c'est juste un prototype pour le moment! En tout cas on commence à avoir un prototype qui à l'air un peu vivant, et ça, c'est ultra classe :D Vous remarquerez aussi qu'une fois arrivés sur place, le compteur "people" s'incrémente, histoire qu'on sache combien la ville a d'habitants.

Du coup, c'est tout pour aujourd'hui, la prochaine étape sera de faire un déplacement un poil plus intelligent, par exemple suivre une route, ou éviter les arbres.

Sur ce des bisous les blogouzes, a la prochaine!

vendredi 28 septembre 2018

[Jour 16] C'est à cette heure ci que tu rentres?

Oui, je suis de retour, douze ans plus tard. Ok j'ai dit que j'allais faire 50 jours d'affilée, mais j'ai jamais dit que y'aurais pas de pauses




Bref, cet article sera assez court parce que ben, j'ai passé douze ans a faire des mises a jour en fait, mais j'ai repris. J'ai changé la maniere dont les arbres sont gérés. Avant, un arbre, c'était un bloc de terre avec un arbre dessus. Maintenant un arbre, ben c'est un arbre.

J'ai du refactoriser beaucoup de code, mais du coup, maintenant, on a des arbres qui sont posés sur les blocs de terre, et donc que l'on pourra retirer par la suite. Je me suis dit que ça pourrait être utile un jour.


Voilà article terminé, le prochain objectif, c'est de faire en sorte de faire rentrer de l'argent :) A bientard

lundi 16 juillet 2018

[Unity3D][Défi50Jours] Jour 15 - ARJEN



Bonjour, aujourd'hui on va parler d'un truc important: l'ARJEN



Alors, oui j'ai pas donné de nouvelles pendant plus d'une semaine, mais j'étais pas là et après j'étais malade, du coup j'ai pas bossé. Mais je suis revenu, et c'est pas important, l'important comme je vous l'ai dit, c'est l'ARJEN, avec un grand J.


Car oui, ça y est, après une grande session d'environ 4h, j'ai ajouté le système de POGNON, de FLOOZ, le système capitaliste comme tu l'aimes. Tu veux poser une maison? OK, mais maintenant va falloir PAYER mon gars et ouais. Une route? Crache tes biftons. T'as plus d'ARJEN? Ben tant pis, tu verras tout rouge, et tu posera plus rien. Faudra attendre la prochaine maj avant de pouvoir regagner du POGNON, déso pas déso.


Du coup, la partie commence avec 1000 d'ARJEN, et une portion de route coute 5 ARJEN tandis qu'une maison en compte 100. Voyez-ci après des exemples d'utilisation de l'ARJEN.

PLINDARJEN.jpg

PUDARJEN.jpg
Et bien sûr tout est sauvegardé, comme ça si tu es pauvre, tu seras toujours pauvre en revenant. MALINX LE LINX

Pour expliquer vite fait comment ça marche, j'ai créé une classe ressource, qui a comme paramètre un nom et une quantité. J'y ai ajouté une fonction d'ajout qui ajoute simplement un nombre à cette quantité.
Dans la classe Game, j'instancie un objet Resource, avec les paramètres de départ "ARJEN" et 1000. Vous pouvez aussi voir qu'il y a un objet instancié avec les paramètres "people" et 0, mais pour l'instant on s'en sert pas.
Ensuite, sur la classe bâtiment, j'ai ajouté une variable "cout" avec une valeur par défaut a 5. J'ai ensuite créé une fonction "Create" que l'on va appeler lorsqu'on pose l'objet sur le sol, qui s'occupe simplement d'enlever la valeur cout au total de l'ARJEN. Ensuite, pour les Maisons, qui sont une extension de la classe Bâtiment, j'ai simplement changé le cout à 100.

Ensuite, la partie un peu plus dure, c'est de rester au dessus de zéro. Dans la partie qui sert à poser les objets, il faut faire plusieurs choses:
- détecter le type de l'objet en sélectionné
- le peindre en rouge si son coût est supérieur à l'ARJEN restant
- ne pas poser si l'objet est en rouge, poser et appeler la fonction Create de l'objet sinon



Bon, pour les maisons c'était simple, par contre pour les routes, hummm. Le principe est le même, sauf que, comme il y a un cliqué glissé, il faut effectuer ces opérations a chaque mouvement de la souris, et sur le nombre total de routes affichées. Et enfin, lorsque l'utilisateur relâche le bouton, si on était en rouge, il faut supprimer les routes. Je vous épargne le code en lui même, mais autant vous dire que tout ça a demandé beaucoup de temps et d'essais, mais maintenant tout marche.

Dernière chose importante, montrer l'ARJEN à l'écran. Bon là c'est tout moche, parce que y'a toujours pas d'UI, mais l'ARJEN c'est l'ARJEN, UI ou pas.

Du coup voilà qui conclut notre article du jour. On a de plus en plus quelque chose qui ressemble à un jeu ! La prochain étape du coup, c'est de pouvoir faire rentrer de l'ARJEN, avec notamment l'ajout de micro-transactions centres des impôts par exemple.



Sur ce des bisous, et à la prochaine! 

jeudi 5 juillet 2018

[Unity3D][Défi50Jours] Jour 14 - Le jeu des devinettes

Salut lecteur.

Aujourd'hui j'ai la flemme de faire un grand article, alors on va jouer à un jeu ok? Ok, de toute façon soit tu joues le jeu soit tu t'en vas j'ai dit que j'allais pas écrire hein.
Donc voilà le jeu: je mets un gif, et tu devines ce qui a été ajouté durant la dernière session. Prêt?

Superjeu.gif

Ca devrait être assez facile. Et niveau code rien qui n'a pas déjà été vu, c'est aussi pour ça que je vous épargne le blabla. Alors, vous avez deviné?

Dites le moi dans les commentaires


Des bisous, la prochaine session on fait vraiment l'UI c'est promis.


PS: il n'y aura pas de sessions de vendredi à lundi inclus, je serais en déplacement et je n'aurais pas de pc

mercredi 4 juillet 2018

[Unity3D][Défi50Jours] Jour 12 et 13 - Améliorations et maisons

Coucou.



Alors oui déso j'ai pas touché au truc ce weekend, et je n'ai pas non plus posté d'updates depuis quelques jours. J'avais la flemme, je fais des journées longues tu sais? C'est compliqué la vie, surtout qu'après le boulot je dois rentrer, me faire à manger, et jouer aux jeux vidéos, du coup c'est dur de trouver du temps !

Mais soit rassuré, toi, lecteur avisé, je suis de retour ! J'ai bel et bien bossé lundi et hier, et oui, j'ai avancé! J'ai même sûrement rattrapé mon retard vu que j'ai fait deux sessions de 3h environs. Et quoi de nouveau vas-tu me demander? Hé bien nous l'allons voir tout de suite.


vendredi 29 juin 2018

[Unity3D][Défi50Jours] Jour 11 - Sauvegarde/chargement des routes

Yo.
Hier, c'était encore une session assez courte malheureusement, il y a eu une soirée imprévue avec le boulot et qui a duré des plombes, du coup je n'ai pas eu le temps que je voulais pour coder.
Mais j'ai quand même une bonne nouvelle, la pose des routes est maintenant finalisée :)

Hier, pendant le peu de temps que j'ai eu pour coder, j'ai tout de même pu mettre en place le système de sauvegarde et chargement des routes.

Pour faire simple, jusque là nous avions l'objet TileObject, qui représentait un point de notre map, avec sa position et son type (Grass, Dirt...). Ici, j'ai créé un nouvel objet nommé BuildingObject, qui pourra être utilisé pour tous les types d'objets posable sur la map. Il contient le type de building ainsi que son orientation. Et il suffit ensuite de dire que chaque TileObject peut maintenant contenir un BuildingObject.

Lors de la construction de chaque morceau de route, on va créer le BuildingObject correspondant et on l'ajoute au TileObject qui se situe sous cette route. Pour supprimer une route, il faudra d'abord supprimer à l'écran le GameObject route, puis supprimer le BuildingObject contenu dans le TileObject correspondant. Et une fois fais, tout se sauvegarde.
(A noter que la manière de sauvegarder les objets est pour l'instant adéquat car un morceau de route fait la taille d'une case, mais si on se met en tête de faire des bâtiments qui peuvent faire plusieurs cases de long ou de large, il faudra peut être changer ce système pour autre chose.)

Pour ne pas conserver les routes à l'écran lorsqu'on change de map, il suffit de supprimer tous les BuildingObject contenus sur la map.

Ensuite, pour le chargement, lorsqu'on instancie chaque case de notre Map, on vérifie si un BuildingObject existe, et ci c'est le cas on instancie le préfab correspondant et on lui applique une rotation en fonction de la direction qui lui est assignée.


Sauvegarde/chargement exemple


Et c'est tout! C'est assez simple au final, ça marche comme il faut, et du coup maintenant on a tout ce qu'il nous fallait pour les routes. Du coup la prochaine étape, ça va être la gestion des ressources, et la pose d'autres type de buildings, avec l'interface et tout et tout. A très vite pour l'update du jour 12!