Wonse : Can I Really Be a Developer?

Je joue, je crée le blog de Wonse.

Unity D-RPG #3 base de combat et objets

Tuesday 29 April 2014 à 22:19

Cette fois, j’ai ajouté plusieurs petites choses.

Premièrement, j’ai fait en sorte que le joueur puisse se tourner et se déplacer en diagonale. Pour ça, comme pour le pathfinding, je vérifie si les 2 cases à côté sont viables, en plus de celle de destination.  (Touche 1-9 du numpad)

Il y a une base d’inventaire. On peut donc, si l’on est sur une case avec un objet, le ramasser en cliquant sur le bouton qui s’affiche à l’écran. L’objet est donc placé dans la fenêtre d’inventaire, à droite de l’écran. Avec la possibilité de le reposer (en cliquant sur drop) ou de l’utiliser (en cliquant sur use).

Actuellement, il y a 2 types d’objets : les consommables (la pomme, qui rend 20 PV), et les armes.

J’ai aussi fait en sorte que les ennemis attaquent. Une fois à côté du joueur, à leur tour, ils donnent un coup d’épée, qui inflige quelques dégâts (le joueur ne peut pas mourir)

Le joueur peut lui aussi attaquer (Espace), ce qui inflige quelques dégâts à l’ennemi sur la case devant lui.

Tant qu’à faire, j’ai ajouté une gestion élémentaire. Feu > Air > Terre > Eau > Feu … Rien de très original.   Pour tester ça, j’ai donc intégré 3 ennemis, chacun d’un élément différent, ainsi qu’une épée de feu. (J’en ai profité, au passage, pour utiliser des models achetées en promo pour un autre projet)

Pour essayer ça, il suffit de cliquer sur l’image.   le numpad pour se déplacer / se tourner, et espace pour frapper (les touches sont bien entendu temporaires, je travaillerai là-dessus  une autre fois)

script_drpg03
CLIC HERE TO PLAY

Il est possible de commencer “dans le vide”, ou même que le joueur est les ennemis ne puissent pas se rejoindre.  Le terrain de jeu est pour l’instant aléatoire sans gros travail dessus; si i ly a un soucis de cet ordre, il faut juste redémarrer le jeu

Il y a des choses que je compte retirer ou modifier. Là par exemple, j’ai intégré le fait qu’un monstre cherche un autre chemin si la route est bloquée par un autre.  Sauf que ce que je n’avais pas prévu, c’est que si 2 monstres s’approchent d’un goulet, le premier va passer, l’autre faire demi-tour, et 2 déplacements plus tard, une fois le goulet à nouveau libre, le second va reprendre sa route, alors qu’il aurait mieux fait d’attendre. Je pense modifier ça, peut être en donnant poids de mouvement plus élevé quand il y a un mob obstacle, comme ça il ne prend un détour que si c’est réellement plus rapide que d’attendre 1 tour. Et avanceront en file dans les couloirs.

Pour le ramassage / équipement… j’ai essayé de faire quelque chose qui fonctionne bien, et restera utilisable. alors que certaines choses sont faites, à l’arrache, et sont juste temporaires (le carré pour indiquer la cible ou l’interface, par exemple)

Unity D-RPG #2 Pathfinding

Saturday 26 April 2014 à 0:20

Aujourd’hui, l’idée était d’intégrer dans le jeu le pathfinding fait la dernière fois.
J’ai apporté des modifications mineures. Ma fonction de pathfind, à la fin, renvoie uniquement la première case du déplacement. (car le chemin est recalculé au début de chaque tour).

Au passage, j’ai ajouté des cases “vides” sur lesquels on ne peut pas marcher (qui servent donc de mur, pour ce qui est du pathfinding.)

En étant dans l’éditeur, j’en ai profité pour faire une petite fonction pour m’afficher le chemin avant que l’ennemi avance. Qui m’a d’ailleurs bien servi pour débugger et peaufiné tout ça.

pathray

Dans le build, il y a le personnage qui suit le joueur, en restant toujours sur une case à côté de lui. Il est possible que le personnage commence dans le vide ou que le joueur et l’ennemi ne puissent pas du tout se rejoindre, dans ce cas, il faut juste restart

script-loot

CLIC HERE TO PLAY

Je me rend compte que j’ai oublié certaines choses basiques. Là par exemple, je vérifie  si il y a un obstacle (un autre montre) au moment de déplacer le personnage et si c’est le cas, il attend Sur place. Alors qu’il devrait juste prendre un autre chemin.

Ajout de la prochaine version : Se déplacer en diagonal pour le héro, gérer des objets par terre et en inventaire,  Base de combat, peaufiner le pathfinding pour que plusieurs ennemis puissent se déplacer sans accroc

Unity #16 : Pathfinding A* (2)

Monday 21 April 2014 à 19:09

Avancée dans le pathfinder en a*.
( Voir posts précédents pour la progression )
Aujourd’hui, j’ai avancé dans le pathfinder en intégrant plusieurs petites choses pour améliorer les performances et les possibilités du pathfinder.

1. J’ai ajouté des tiles de mur (en noir) sur lesquels on ne peut pas se déplacer. Les tiles ont donc un état “utilisable” à “vrai” pour les sols normaux et à “faux” pour les murs ( logique booléenne ). Lorsque je vérifie les voisins d’une dalle, je vérifie pour chacun s’il est utilisable. Si ce n’est pas le cas, je l’ignore.

2. Je voulais aussi faire en sorte que l’on puisse se déplacer en diagonale sur 8 axes plutôt que 4.
Pour ce faire, au moment de lister les voisins, je vérifie aussi les cases en diagonale. Je donne un poids de mouvement de 14 lors des déplacements en diagonale plutôt que le 10 habituel.

3. Le soucis avec l’ajout des déplacements diagonaux, c’est que le déplacement semble parfois passer à travers certains murs. En effet, comme on peut voir sur l’image ci-dessous, laisser le pathfinding comme ça amènerait des soucis. J’ai donc décidé de ne laisser passer le chemin diagonal que si les deux directions voisines directes sont elles aussi des cases valides. Par exemple, on ne peut aller vers le nord-ouest que s’il est possible d’aller vers le nord et vers l’ouest. Le chemin ne passera donc plus à travers les coins de murs.

wall11

4. J’ai ajouté de l’heuristique. C’est à dire une façon d’orienter mon pathfinding pour gagner en rapidité de recherche, quitte à perdre un peu en précision.

Pour ça, une fois que je crée un noeud, je lui donne une valeur heuristique H selon sa distance avec le point d’arrivée. Les cases proches de l’arrivée auront donc un poids H très faible alors que les points éloignés en ont un plus élevé.

Ensuite, lorsque je vérifie le poids des voisins d’une case, en plus de prendre le poids de déplacement (10 pour les droites et 14 pour les diagonales), j’ajoute le poids de l’heuristique au calcul. Il aura tendance à préférer une case plus proche de la sortie. Il fera donc, en tout, beaucoup moins de vérifications superflues.

Je peux moduler la “puissance” de l’heuristique. Une valeur très élevée pourra entraîner une recherche plus rapide mais encore plus imprécise.

heuristic01

Dans l’exemple ci-dessous, j’ai ajouté toutes ces modifications et il est possible de choisir le niveau de puissance de l’heuristique.

Les murs (en noirs) sont placés aléatoirement, il est donc possible d’avoir des trajectoires infaisables


script-astar02
CLICK HERE TO PLAY

Je pense que ma recherche de chemin actuelle est déjà suffisante pour être intégrée au jeu. J’y ajouterai sûrement quelques paramètres pour la suite. ( gestion de hauteur de saut, par exemple.) J’ai aussi fait 2-3 modifications pour gagner en performance.

Unity #15 : Pathfinding A* (1)

Friday 18 April 2014 à 14:58

Petite tentative de pathfinding (Recherche du plus court chemin) en A* sur Unity

La dernière fois, j’ai créé un terrain quadrillé.  Je veux que les ennemis puissent s’attaquer au joueur et, pour ça, il va falloir qu’ils puissent l’atteindre. Dans ce but, il va falloir faire du pathfinding ! (recherche de chemin).

J’ai décidé de faire du A* car j’en ai déjà quelques notions et ça semble adapté à un jeu sur grille.
Pour garder les choses simples je crée un nouveau projet (j’adapterai par la suite le pathfinding au jeu, une fois que j’aurai quelque chose de satisfaisant).

1. Je crée une grille de cases (avec un ID et une position)
2. Je définis un point de départ ( case bleue ) et un point d’arrivée (case rouge)
3. Le pathfinder récupère chaque case du terrain et crée un “noeud” pour chacune.
4. Je vérifie et enregistre, pour chaque noeud, ses voisins directes ( en général, 4 voisins, sauf si on est près d’un bord).
Chaque nœud possédera aussi un parent, (non défini au début, qui sera déterminé plus tard) et un poids (0 au départ).

5. Je lance la véritable recherche de chemin.  Pour ça, j’ai 3 listes :
- Une liste qui contient tous les nœuds “ouverts”
- Une liste qui contient l’ensemble des nœuds
- Une liste qui contient tous les nœuds“fermés”, que je n’ai plus qu’à vérifier ou modifier

5.1 L’idée est de prendre le nœud de la liste ouverte qui a le “poids” le plus léger. Il devient alors le noeud “actif”.
5.2 Le mettre dans la liste fermée
5.3 Vérifier tous ses voisins,

Pour chaque voisin, si il n’est pas en liste ouverte, je le place en liste ouverte, et je lui définis le noeud “actif” comme parent ainsi qu’un poids égal à celui de son parent + le coût de déplacement (dans mon cas, le coût est 10)
Si le voisin est déjà en liste ouverte, alors je compare son poids avec celui du noeud “actif”.  Si le poids du noeud actif + coût en déplacement est plus faible que le poids du voisin,  cela signifie qu’il sera plus court de passer par le noeud actif que par son parent précèdent pour se déplacer jusque là. Je définis donc le noeud “actif” comme son nouveau parent et lui définis son nouveau poids.

Une fois chaque voisin du Noeud actif vérifié, je recommence au point 5.1.  Donc prendre le poids le plus léger, vérifier et éditer ses voisins… jusqu’à atteindre l’arrivée.
5.4 Une fois l’arrivée atteinte, on n’a qu’à retracer le chemin de la fin vers le départ en passant par le parent de chaque case.

Voici le script, dans lequel  on peut voir (en ralenti), chaque case vérifiée par le pathfinder.

( un petit clic gauche pour le faire chercher, clic droit pour reset la scène.)

script_astar01

CLICK HERE TO PLAY

Cette version du pathfinder est un peu simpliste, ça ne gère que les cases présentes ou absentes.  Ça ne gère ni l’heuristique ni les coûts de déplacement différents selon le sol ou bien des murs… J’ajouterai donc un peu de richesse pour la prochaine fois afin de le rendre un peu plus utile.

Je me rends bien compte qu’à la lecture, ce n’est pas super clair,  je conseille donc ce tuto video d’explication du A*, pour ceux que ça intéresse : https://www.youtube.com/watch?v=KNXfSOx4eEE ou la page wikipedia : http://fr.wikipedia.org/wiki/Algorithme_A*

Tant que j’y suis, je cherche en ce moment un job de game developer au Canada (Quebec ou Montreal) !

http://thibautgiordano.com/

Unity #14 : Déplacement case par case

Monday 14 April 2014 à 19:07

Depuis quelques mois, j’ai peu posté ici vu que j’ai été embauché à temps plein sur un projet. Mais là, c’est terminé, j’ai donc envie de refaire 2-3 choses par ici.

L’idée, aujourd’hui, est de faire un simple déplacement dans une pièce, case par case et tour à tour, façon jeu de plateau tels Dungeon of Dredmor ou Pokemon donjon mystère, avec en plus une composante de hauteur. Ceci avec une génération procédurale du niveau, très simpliste pour le moment mais je travaillerai peut-être sur une génération plus riche un autre jour.

Donc, première chose, faire un générateur de terrain très simple. Pour ça, je lui définis une largeur et une longueur et, pour chaque unité, je place un carreau(Tile) de 1×1 à la bonne position avec une hauteur aléatoire(nombre entier entre 0 et 3) que je référence ensuite dans un tableau. Pour chaque case, j’enregistre plusieurs informations comme son ID, si on peut marcher dessus, si il contient un personnage ou un objet, sa hauteur…

Dans la classe de gestion des niveaux, j’ai créé quelques fonctions qui permettent de récupérer les informations d’une case par son identifiant ou de récupérer une case par rapport à une autre (par exemple, la case à droite de la case X).

Ensuite, j’ai intégré un personnage joueur. Pour l’instant, il est uniquement capable de se déplacer (sans animations) et de tourner sur lui même. Quand on appuie sur une touche de direction, il se tourne dans la direction correspondante sauf si il est deja dirigé vers cette direction auquel cas il essaye d’avancer d’une case. Pour ça, je vérifie si la nouvelle case existe (si on ne se trouve pas au bord du terrain) et si elle est bien praticable et enfin si la case n’est pas trop haute (2 de hauteur de différence maximum). Si tout ça est possible, je place le personnage sur le carreau demandé .

Pour la gestion des tours, j’ai un manager qui garde une liste de tous les personnages actifs (joueur ou monstres, par exemple) et qui va laisser agir chaque personnage chacun son tour. Dès qu’un personnage a agi, il prévient le manager qui va donner la main au suivant.

J’ai aussi ajouté un ennemi, une simple sphère, qui se déplace en ligne droite mais qui me sert à vérifier si les tours fonctionnent.

script-grid

CLICK HERE TO PLAY

Ce n’est pas très riche pour l’instant, le plus important était de faire le systeme de grille qui fonctionne bien.La prochaine fois, j’essayerai d’ajouter des fonctions là dedans comme des objets par terre ou un système d’attaque/ PV ou alors peut-être un Pathfinding pour l’ennemi.

Ça m’a pris environ une journée pour faire tout ça.

Il reste des choses pour lesquelles je ne suis pas certain. Par exemple, là j’utilise un array qui contient toutes mes tiles du niveau mais peut-être qu’utiliser une liste serait plus efficace (ou en tout cas, plus pratique).

Tant que j’y suis, je cherche en ce moment un job de game developer au Canada (Quebec ou Montreal) !

http://thibautgiordano.com/

Unity 3D-Online Casino

Monday 6 January 2014 à 15:38

Ces derniers mois, j’ai travaille avec des gars de chez Elseware-Experience sur un Prototype de jeu de Casino en ligne.

https://www.youtube.com/watch?v=QkUtCYTFnVw

YouTube Preview Image

Je me suis chargé de la majorité de la programmation.  (je n’ai enregistré que les partie que j’ai programmé, vu que c’est, a la base  juste une vidéo pour mettre sur mon site).

La programmation réseau, c’est assez contraignant, surtout si on veut que des gens puissent se connecter, ou se déco, a tout moment, sans que ça n’affecte les autres. , puissent rejoindre ou quitter une table…

bon, là j’ai pas grand chose a raconter, mais j’essayerai de refaire des posts plus fréquents, pour mes prochains projets

Recherche sur unity #13 : Sprite et plateforme

Friday 20 September 2013 à 15:35

Il a été annoncé à la Unite 2013 que unity3D va prochainement embarquer un vrai moteur 2D,   ça m’a donné envie de faire, avant ça, un petit test des fonctions 2D existantes.
J’ai donc voulu faire un petit jeu de plateforme, en 2D.  avec, dans un premier temps, juste le héros, qui peut se déplacer et sauter.  Avec les animations et sprites qui vont avec.  J’ai un peu regardé dans le moteur, avant de me rendre compte qu’il n’y a pas de fonctions préintégrées, pour faire des sprites 2D.  j’ai donc commencé par là.

SPRITE (image 2D animée) :

Là, l’idée est donc, sur un plan, faire  alterner plusieurs images, l’une après l’autre, pour donner une animation. (je change donc al texture, dans le matériau, toutes les 2-3 frames, selon l’animation)
une fois que ceci fonctionne, j’ai séparé mon manager de sprite, de mes animations (j’ai donc 4-5 anims, liées au manager), lorsque je lance une animation,  si il n’est pas déjà entrain de la jouer, il interrompt la précédente,  et lance la nouvelle, a l’image 1.
Pour chaque animation, je lui définis aussi si elle boucle.  Si c’est le cas, une fois arrivée a la dernière image de son animation, ça repasse a la première image, et ça continue (anim de course).  Sinon, ça reste sur la dernière image de l’animation (anim de chute).

CONTRÔLES:


Ensuite je me suis attaqué aux contrôles du perso.
J’ai décidé d’utiliser le moteur physique d’Unity.  J’ai j’ai un corps rigide sur le perso.  Et j’ai placé quelques cubes avec des collisions dans le monde.
Lorsque l’on appuie sur les flèches, je redéfinis la vélocité (du Rigidbody)  en X
Lorsque l’on appuie sur Espace, si on est a terre, ça redéfinit la vélocité en Y, pour faire un saut.
Pour savoir si on est à terre, je lance, un rayon très court, des pieds du perso, vers le sol. Si le rayon touche le sol, alors le héros est considéré comme à terre.
Lors du saut,  les 500 premières millisecondes, tant que l’on maintien la touche de saut,  j’augmente la vélocité en Y a chaque frame.  Question de pouvoir un peu contrôler la hauteur du saut.
La physique d’Unity étant très “molle” j’ai fait en sorte, lorsque le héros commence a tomber, d’augmenter brutalement sa vitesse de chute (et lancer une anim différente, au passage). pour ça, je vérifie si sa vélocité est suffisamment basse, si oui, j’applique ma nouvelle vélocité en Y
pour que le personnage ralentisse quand on ne touche plus a rien, j’ai mis une valeur de frottement assez élevée

Pour essayer, un petit clic sur l’image ci-dessous.

script-sprite-1CLIC HERE TO PLAY

Pour ce qui est des contrôles, j’ai pas mal chipoté.  je pense que je devrais changer ça pour ne plus modifier la vélocité, mais plutôt en gérant des forces directement. Globalement, je n’aime pas trop la physique d’Unity, et faudra que j’essaye le moteur 2D quand il sera dispo dans Unity. j’ai toujours des soucis de collisions horizontales, et parfois certains mouvements brusques lors de l’atterrissage..

Côté sprites,  il y a beaucoup de boulot pour faire quelque chose de bien, je pense.  Par exemple, ici, ça ne prend pas en compte la taille de l’image.  Donc toutes mes images sont carrées. Mais si je devais utiliser une image plus large, ça serait écrasé.  donc faudrait que je resize le mesh selon la taille de l’image.  (on peut le remarquer au changement de taille lors du saut du perso). Aussi, il faudrait que je puisse contrôler la durée des animations par image, et pas juste pour l’animation , en général. Peut être aussi devrais je tenter de faire un veritable anim tree, donc faire passer d’office uen animation une fois qu’une autre est terminée (animation de vol une fois le saut lancé par exemple, pour ne pas avoi rjuste une image figée…).
Là, j’ai décidé de faire alterner des images. mais peut être, aurais je du avoir une grosse image, et juste déplacer les UV du materiaux ? (faire un Flipbook?) , J’ignore ce qui est le mieux, niveau performance

Le souci étant que pour améliorer ça, il va falloir que je programme ce qui est des fonctions dans l’éditeur (que je mod l’éditeur, en gros) plutôt que le jeu.   ma gestion de sprite actuelle n’est pas valable pour un projet moyen, ou gros).   Si je devais faire un jeu en 2D actuellement, je passerait probablement pas un manager de sprites existant.

Temps total  : Une journée, répartie équitablement en 3  entre : les contrôles, le gestionnaire de sprite, et la rechercher / adaptation / intégration des  images.

Les sprites viennent des jeux Final Fight (de Capcom) et de Super mario world (Nintendo).  Je n’ai aucun droit dessus

http://thibautgiordano.com/

Recherche sur unity #12 : Menu façon Tomb Raider

Sunday 15 September 2013 à 9:37

Aujourd’hui, j’ai voulu faire un menu en 3D, du genre de ce qu’il y avait dans les vieux Tomb Raider,

L’idée est donc de placer différents objets en cercle. Lorsque l’on appuie sur une flèche, on change la valeur de sélection du menu, et on lance une rotation des éléments.  Quand on sélectionne un objet, je l’avance vers la caméra, et je change sa rotation et son échelle progressivement.  Si l’objet a un FX (comme la lampe) ou une animation (comme le livre), ça la lance. Ensuite ça affiche le menu correspondant à l’objet choisi (dans mon, car, mes menus sont vides).

script-menuCLIC HERE TO PLAY

Ici, j’ai fais tout les mouvements de façon procédurales, donc c’est bougé, a chaque frames, en script.  J’aurai probablement eu un résultats plus rapide (Ou justement, plus complexe, mais potentiellement plus riche) , en utilisant des animations faites dans maya, ou autre.  La seule véritable anim, ici, est celle d’ouverture du livre

Temps total,  : 5-6 Heures

Il faut compter environ 1h a galérer a trouver des assets gratuit correctes sur internet (j’ai fini par laisser tomber et faire avec ceux de l’asset store). Et aussi 1h pour modéliser et animer le  livre (j’ai pas trouvé de livre tout fait qui gère l’animation, par contre, j’ai récupéré la texture)

http://thibautgiordano.com/

Recherche sur unity #11 : Zombies En ligne !

Wednesday 28 August 2013 à 11:44

Mise a jours du jeu de frag de zombies, en multijoueur, en ligne.

Il y a 2 jours, j’ai posté un petit jeu, fait en une matinée dans lequel il fallait tuer des zombies. Suite à un malentendu, on m’a conseillé d’ajouter un mode en ligne. Donc, je ne connais pas vraiment ça (j’ai un peu touché au networking avec un plug-in (Tnet), mais ici, ça ne collerait pas, vu que ça nécessite un serveur. J’ai donc fait ça avec les fonctions de réseau de base Unity. Étant un gros débutant là dedans, je suis parti d’un petit tuto, et j’ai brodé tout ça autour de mon jeu.

Le jeu :

Le jeu se joue à 2 joueurs.

Chaque joueur a une couleur (Bleu, ou Rouge), chaque zombie aussi. Les zombies bleus attaquent le joueur rouge, et les zombies rouges attaquent le joueur bleu. Le but est de survivre le plus longtemps possible, mais pour chaque zombie tué, 2 nouveaux apparaissent, l’idée est donc de tuer les zombies de l’autre joueur, sans blesser les siens. Dès qu’un joueur a subi 10 coups, il perd, et le jeu s’arrête. Les joueurs ne peuvent pas se tirer dessus l’un l’autre

Contrôles :

Le jeu est prévu pour être joué au Pad 360.

Joystick gauche pour déplacer le personnage, Joystick droit pour déplacer la caméra (quand on ne lock pas).
À pour tirer, Y pour sauter. B pour locker ou délocker un ennemi
LB/RB pour passer d’une cible a l’autre

Pour ceux qui n’ont pas de manette, j’ai bricolé un contrôle a la souris, mais le jeu n’est pas prévu pour ça a l’origine, et certaines choses ne passent pas trés bien.

ZQSD pour déplacer le personnage, bouger la souris pour déplacer la cameracaméra (quand on ne lock pas).
Clic gauche pour tirer, Espace pour sauter. Clic droit  pour locker ou délocker un ennemi

E pour passer d’une cible a l’autre

Pour essayer, un petit clic sur l’image ci-dessous. Pad 360 et webplayer unity conseillés

script-zombieonlineCLIC HERE TO PLAY

Ce que j’ai compris du réseau :

Vu que je partais presque de zéro, en terme de réseau, j’ai beaucoup chipoté, une première base est simple : un joueur héberge, son serveur est disponible dans la liste, un autre peu cliquer pour le rejoindre, ils sont connectés !  Sauf qu’en fait,  si on n’explique pas a chaque objets/actions, d’agir en réseau, c’est juste 2 joueurs, chacun de leurs cotés, qui ne se voient même pas l’un l’autre, avec aucun objets ou éléments en commun.

Pour mettre les choses en réseau, je dois changer  plusieurs choses. Par exemple, lorsque j’instancie un prefab, le faire via une fonction instanciation de la Class de réseau,  l’”objet” apparaîtra donc chez les deux joueurs. mais une fois en jeu,  il tournera localement sur chaque machine, si je ne lui donne pas d’info pour se synchroniser

Pour ça, j’ai en gros accès à 2 méthodes. Pour une, je dois ajouter un composant (network view) a un prefab, qui va s’assurer a une fréquence donnée,  de mettre a jours certains infos, si elles ont été modifiées. Par exemple, si j’y assigne la position du joueur. Tant que le joueur ne bouge pas, rien n’est envoyé, mais si il se déplace (de lui même, ou parce qu’on le pousse, ou peu importe le moyen), il enverra sa nouvelle position au réseau, et le personnage sera ajusté dans le jeu des autres joueurs. Et ce, plusieurs fois par seconde.

Une autre méthode consiste a appeler, “moi-même”, des fonctions en   [RPC],  qui seront exécutées , sur le réseau, par le personnage, chez tous les joueurs. (ou juste chez certaines, si je définis lesquels)

Vu que les héros ont le même script de contrôle,  chaque joueur contrôlait les 2  héros simultanément, j’ai donc du m’assurer, dans la boucle de contrôle, de ne le contrôler que si le personnage appartient au joueur.(networkView.isMine).

Pour la caméra,  chaque joueur dois voir son propre personnage, mais je n’ai pas besoin d’avoir 2 caméras dans la scène pour autant, j’ai donc fais en sorte que chaque joueur, au lancement, prenne le contrôle de la caméra, et comme je ne mets  jamais a jours la caméra sur le réseau, la caméra suivra toujours son héros, pour chaque joueur.

Les mouvements des  joueurs

Les position et rotation des joueurs sont,  a ce moment, mis a jours par le réseau (avec le network view, comme dis plus haut), mais seulement plusieurs fois par secondes, donc très saccadées. Pour interpoler ça, j’ai utilisé un script NetworkRigidbody.cs, des tutoriaux unity officiels, qui ne va pas se limiter a changer la place du perso 10 fois par seconde, mais qui va interpoler et extrapoler les positions et rotations.

Donc là, on a les persos qui se déplacent sur le réseau, seulement voilà, ils n’ont aucune animation. En effet, je modifie les animations a jouer au moment ou je contrôle le personnage, en définissant à chaque frame,  des valeurs aux paramètres du gestionnaire d’animation (component Animator). Mais vu que le joueur ne contrôle plus que son personnage, toute cette étape est ignorée, Il faut donc, trouver un moyen de transmettre les animations sur le réseau. , j’ai envisagé plusieurs moyens.

Première idée : utiliser des fonctions de RPC, et dés que je donne une valeur a mon animator, je préviens sur le réseau. Mais ça ne me semble pas viable, vu que je mets à jour plusieurs informations à chaque frame, et que je ne veux pas saturer la lignes avec des informations non primordiales.

Deuxième idée : vu que j’ai une interpolation des positions, je peux récupérer la vitesse de mouvement actuel du personnage, et à partir de ça, calculer ses informations d’animations de marche, sauts… Et a coté de ça, utiliser la première idée pour ce qui est des animations moins fréquentes, comme le tir,  je ne mettrai a joueur les infos de tir que lorsque je lance vraiment un projectile.

Troisième idée :  Ajouter un script au personnage, à part de ceux de contrôles et de mouvements. ce script va en permanence regarder l’état de presque tout les  paramètres de l’animato, et s’il voit qu’il y a eu un changement de valeur dans un des paramètres, alors il va l’enregistrer, et envoyer sur le réseau la nouvelle valeur. C’est la méthode que j’ai décidé d’employer, et a priori, ça fonctionne. La seconde méthode doit, par contre, être plus légère en terme de bande passante, mais je préférais avoir un contrôle sur toutes les animes, avec la même logique

Les mouvements des zombies

Pour les zombies, a priori, ça sera plus simple, vu qu’il n’est pas contrôlé par les joueurs, et a une IA simple, j’ai juste a les faire spawn au même endroit, et a le laisser se débrouiller, il va chasser les joueurs, dont les positions sont synchronisées. Sauf qu’en fait, ça ne marche pas.
En effet, si la position du joueur était exactement la même synchro sur le réseau, ça irait, mais là, on extrapole. Donc il suffit d’un petit décalage, pour que le zombi soit décalé très légèrement par un obstacle, pour qu’il prenne un chemin différent. Et qu’au final, après 10 secondes, soit à des endroits très différents pour chaque joueur. (Ce qui n’est pas vraiment grave en fait, je pense, mais pour ce script, je voulais quelque chose de plus juste)

A la place, j’ai donc plutôt utilisé quelque chose de plus proche que ce que j’ai fait pour les persos. Le script de NetworkRigidbody, pour la position dans le monde. Mais par contre, il fallait a ce moment là, que je m’assure que le zombie ne soit pas calculé chez les deux joueurs (auquel cas il se déplacerait 2 fois plus vite, et aurait des soucis de synchro.  Donc j’ai fait en sorte de vérifier qui est le “propriétaire” du zombie. (en gros, celui qui l’a fait spawn), et c’est donc chez un seul des deux joueurs que le zombie fera ses vrais calculs, complets. Chez l’autre, j’ai gardé une partie des calculs locaux, mais sans toucher à certaines choses, comme les déplacements. Par contre, je lui laisse calculer en local toute la partie animation, qui n’aura donc pas à transiter sur le réseau.

À y réfléchir maintenant,  j’aurais peut-être dû laisser les déplacements complets en local de chaque côté, mais vérifier, occasionnellement, la position, et la synchroniser, si elle est différente (ce qui n’est pas le cas la plupart du temps, a moins de lagguer)

Les tirs

Pour les tirs des joueurs, il était évident que je ne pouvais pas les synchroniser trop souvent, vu qu’on tir tout le temps et qu’il y a donc beaucoup de balles à la fois.
Quand un joueur tir, je crée une balle sur le réseau. Au départ, j’ai laissé tel quel, en me disant que si ça touche, ça touchera le même ennemi chez les deux joueurs. Mais comme pour les calculs de mouvements des zombies, ça m’a vite semblé trop approximatif (et je ne veux pas avoir un zombie blessé chez un joueur, mais en pleine forme chez l’autre..) .

Ce qui m’a paru le plus simple, pour finir, a été de modifier juste le script de la balle, pour qu’au moment du contacte,  elle ne fasse les calcules de dégâts, et autre, uniquement chez le propriétaire. Et la balle est détruite ensuite non pas sur le réseau, mais en local. Comme ça il est possible d’avoir une imprécision pour l’autre joueur, mais uniquement visuelle.

Pour ce qui est des dégâts, l’idée générale est donc d’appeler une fonction de réseau quand le zombie subit des dégâts, pour prévenir l’autre joueur. Et ensuite, seul le propriétaire va vérifier l’état de santé. et si il a moins de 0 PV, alors il appelle la fonction pour faire spawn 2 zombies, et détruit le zombie mourant sur le réseau,  puis incrémente le compter de fraggs.

J’ai eu beaucoup de petits soucis pour ajouter le réseau dans ce script. Certains problèmes que j’ai compris, et corrigés. Et d’autres que j’ai juste contournés sans les comprendre. Par exemple a l’origine, j’envoyais un point pour compter les frags justes avant d’annoncer la mort du zombie sur le réseau. Mais l’autre joueur semblait ne pas pouvoir lancer la fonction, car il avait l’air de recevoir l’ordre de destruction avant celui de comptage de points. Pour contourner ça, j’ai fait ajouter un point lors de l’appel de la  fonction “Ondestroy” interne au moteur, qui est appelé lors de la destruction de l’objet.

Aussi, j’ai l’impression que ce qu’on fait par le réseau est toujours très vague. On n’est jamais certaines des données que les autres vont recevoir toutes les infos, de ce que le lagg peut faire au jeu. Je pense que faudra que je m’achète et lise attentivement un bouquin sur la théorie de développement de jeux en réseau, avant de pouvoir faire quelque chose de bien.

Temps : 10 Heures pour la mise en reseau, mais en repartant du script fait la dernière fois (donc environ 30h en tout)

PS : Ce post est un peu chaotique et confus, mais mon esprit l’est aussi, aujourd’hui, donc c’est normal

http://thibautgiordano.com/

Recherche sur unity #10 : Zombies !

Saturday 24 August 2013 à 11:36

Et voilà, j’ai très peu de temps ici en ce moment, vu que je passe le plus clair de mon temps à travailler sur un projet professionnel (j’apprends, au passage, à faire des jeux en ligne), ou à déménager.

Mais j’ai quand même pris une petite matinée pour faire un petit jeu.

Cette fois, je ne suis pas reparti de zéro,  j’ai repris le script de déplacement / tir… que j’avais fait la dernière fois.

J’ai remplacé les petits cubes sans honneur, par de valeureux zombies.  Auquel j’ai ajouté un  petit script avec une IA superficielle ( les zombies, c’est une bonne excuse pour ne pas trop réfléchir).  Donc, en gros, ils ciblent le héros, avancent en ligne droite vers lui.   Une fois à coté de lui, une attaque simple, qui inflige 10 dégâts.

Pour le “jeu”, il faut quelques balles pour tuer un zombie,  et quand ça a lieu, 2 nouveaux zombies apparaissent sur la map. Loin du héros (pour ça, j’ai une dizaine de points de spawns, et je m’assure de ne pas être proche du player, au moment du spawn),  le but est de tuer le maximum de zombies.

J’ai placé tout ça dans un terrain tout fait chopé sur l’asset store

Pour essayer, un petit clic sur l’image ci-dessous. Pad 360 et webplayer unity conseillés

script-cimetiere CLIC HERE TO PLAY



Temps : 4 Heures, mais en repartant du script fait la dernière fois (donc 18-20h en tout)

http://thibautgiordano.com/