Вы находитесь на странице: 1из 116

Crez

des jeux de A Z avec Unity

IV. Rseau et mode multijoueur


par
Anthony Cardinale
Aperu gnral de louvrage

Le livre ou le module que vous avez sous les yeux a t publi dans le cadre dune srie ddie au dveloppement de
jeux avec Unity Crez des jeux de A Z avec Unity. Chaque module a t conu pour pouvoir tre lu indpendamment.
Libre vous de ne lire que ce qui vous intresse !
Crez des jeux de A Z avec Unity - IV. Rseau et mode multijoueur
par Anthony Cardinale
ISBN (EPUB) : 978-2-8227-0385-7
Copyright 2015 ditions D-BookeR
Tous droits rservs
Conformment au Code de la proprit intellectuelle, seules les copies ou reproductions
strictement rserves lusage priv du copiste et non destines une utilisation collective
ainsi que les analyses et les courtes citations dans un but dexemple et dillustration sont
autorises. Tout autre reprsentation ou reproduction, quelle soit intgrale ou partielle,
requiert expressment le consentement de lditeur (art L 122-4, L 122-5 2 et 3a).
Publi par les ditions D-BookeR, 5 rue Delouvain, 75019 Paris
www.d-booker.fr
contact@d-booker.fr
Ce module fait partie de louvrage global intitul : Crez des jeux de A Z avec Unity
ISBN (HTML) : 978-2-8227-0404-5
Les exemples (tlchargeables ou non), sauf indication contraire, sont proprit des
auteurs.
Mise en page : gnre sous Calenco avec des XSLT dveloppes par la socit NeoDoc
(www.neodoc.biz)
Image de couverture : iStockphoto
Date de publication : 29/10/2015
dition : 1
Version : 1
propos de lauteur
Anthony Cardinale
Dveloppeur passionn de jeux vido, Anthony utilise Unity depuis 2008. cette date, le
logiciel commence tout juste se faire connatre en France, et il compte parmi les
premiers ladopter. Auteur de plus dune trentaine de jeux publis sur Google Play,
lApp Store ou Windows Phone Store, il sest peu peu spcialis dans les applications
destination des mobiles et tablettes, aprs avoir galement dvelopp pour le web et les
PC.
En parallle, Anthony maintient diffrents sites de-learning. Il a ralis ce jour plus de
200 heures de formation vido sur la cration de jeux avec Unity, diffuses via son site
internet Formation facile.
Introduction
Depuis que les jeux vido existent, ils nont cess dvoluer et de sadapter la demande
des joueurs toujours plus exigeants. Les diteurs de jeux vido doivent sadapter au
march et aux nouvelles consoles pour ne pas se laisser dpasser par la technologie.
Au dbut, dans les annes 1960, il y a eu les bornes darcade, en 1970 sont apparues les
premires consoles de salon avec un simple joystick un bouton, puis les annes
80 marquent le dbut des premiers ordinateurs personnels ainsi que la cration de jeux au
succs plantaire comme Pac-Man ou encore Space Invaders. En 90, les consoles de salon
deviennent de plus en plus populaires puis les jeux 3D sont apparus pour devenir
quasiment des standards dans les annes 2000.
Aujourdhui, les consoles et le jeu vido ont encore volu pour sadapter
lomniprsence dInternet. Il nexiste plus de consoles ne proposant pas de connexion
internet. Internet est partout, que ce soit sur nos ordinateurs, nos consoles de salon, nos
consoles portables ou encore nos tlphones ou tablettes, qui sont de vraies consoles de
jeux, tous ces appareils nous permettent de nous connecter au web.
Les joueurs demandent toujours plus de fonctionnalits et Internet est devenu une
composante indispensable dans un jeu vido. Il permet de stocker des informations en
ligne, de partager des donnes comme un score, de jouer un mme jeu partir de
plusieurs terminaux ou encore de jouer plusieurs un mme jeu au mme moment, cest
ce que lon appelle les jeux en rseau.
Parmi tous les types de jeux, les jeux en ligne multijoueurs sont les plus difficiles
dvelopper car toutes les donnes doivent tre synchronises en mme temps sur tous les
crans. Se posent aussi des questions de scurit car chaque joueur est reli aux autres
joueurs par lintermdiaire dun serveur. Mais la demande est bien l, et ne pas proposer
de mode multijoueur dans un jeu revient renoncer une grande partie du march.
crire ce livre a t pour moi un vrai dfi. Son but est de vous apprendre coder vos jeux
en rseau avec Unity 5 et son nouveau systme UNET (Unity Networking). Nous
partirons du jeu dvelopp en exemple dans le livre III. Concevoir un jeu 2D et nous lui
ajouterons un mode multijoueur en ligne. Cela nous permettra de nous concentrer
exclusivement sur les fonctionnalits rseau. Dans la pratique, il est prfrable dintgrer
ds la conception le mode multijoueur.
1. Ce dont vous avez besoin et prrequis
Ce livre suppose que vous savez crer un jeu monojoueur. Si ce nest pas le cas, nous vous
recommandons la lecture des livres prcdents de la srie Crez des jeux de A Z avec
Unity.
Lintroduction du module UNET a considrablement simplifi le dveloppement des jeux
rseau. Vous aurez quand mme besoin dun bagage technique lmentaire, savoir
quelques notions en PHP, MySQL et JSON.
Pour suivre ce livre, vous devez avoir install le logiciel Unity sur votre machine. UNET
tant apparu avec la version 5.1, veillez le mettre jour si vous disposez dune version
antrieure. La version Personal est suffisante.
Vous devez galement tlcharger les sources du jeu dvelopp de tir dvelopp dans le
livre III. Concevoir un jeu 2D ainsi que celles du prsent livre (galement disponibles
depuis longlet Complment de la fiche de prsentation du livre sur le site de lditeur).
2. Quallez-vous apprendre dans ce livre ?
Chapitre 1 - Notions fondamentales du rseau
Pour commencer, nous verrons comment fonctionnent les jeux en ligne, comment les
donnes sont synchronises sur le rseau et quelles sont les techniques de mise en
rseau.
Chapitre 2 - Dcouverte dUNET
Ce chapitre prsente les principales fonctionnalits proposes par UNET. Il sagit en
fait dune liste de fonctions qui par la suite vous aidera comprendre pourquoi
utiliser tel composant plutt que tel autre.
Chapitre 3 Mise en rseau
Partant de notre jeu dexemple, nous verrons comment mettre en place un mode
multijoueur et permettre ainsi plusieurs joueurs de se connecter une mme scne
et contrler leur personnage.
Chapitre 4 Instanciation sur le rseau
Tous les lments instanciables comme par exemple les projectiles des armes doivent
tre configurs de sorte apparatre sur le rseau, cest--dire sur les crans de tous
les joueurs. Cest ce que nous apprendrons faire dans ce chapitre.
Chapitre 5 Interactions entre joueurs
Nous verrons comment synchroniser des informations sur le rseau et faire en sorte
que lorsquun joueur est touch par un projectile, lensemble des joueurs connects
au jeu en soit inform.
Chapitre 6 Optimisation pour le rseau
Pour viter les ralentissements et les bugs, nous verrons comment diminuer le
nombre dinformations qui transitent par le rseau.
Chapitre 7 Cration dun menu personnalis
Nous utiliserons ici les fonctions propres UNET pour crer le menu principal de
notre jeu.
Chapitre 8 Menu Options et modes de jeux
Dans ce chapitre, nous verrons comment grer le mode de jeu, par exemple le niveau,
le nombre de joueurs, etc.
Chapitre 9 Utilisation dune base de donnes
Ici nous verrons comment associer le jeu une base de donnes pour conserver des
informations sur un serveur web.
Chapitre 10 Cration dune API PHP
Vous dcouvrirez comment dvelopper une API avec le langage PHP. Cette API
permettra de communiquer avec le serveur web partir de notre jeu Unity.
Chapitre 11 Utilisation de lAPI avec SimpleJSON
Dans ce chapitre, nous verrons comment communiquer avec lAPI en utilisant la
classe WWW ainsi que le plug-in SimpleJSON.
Chapitre 12 Intgration de fonctionnalits bien utiles
Il est toujours possible damliorer un jeu par exemple en ajoutant quelques
fonctionnalits supplmentaires. Dans ce chapitre, nous allons voir comment intgrer
le partage sur les rseaux sociaux, un systme de notation/avis et lenvoi de-mails,
ainsi que la possibilit dafficher des banires en vue de futurs partenariats.
Foire aux questions
Vous trouverez ici rponses quelques questions que vous ne manquerez
certainement pas de vous poser !
3. Comment bien apprendre avec ce livre ?
Au cours des diffrents chapitres, chaque fois que nous dvelopperons un script, je
commencerai par vous prsenter les fonctions dont nous aurons besoin et vous expliquerai
quoi elles servent. Pour bien apprendre, je vous invite essayer de dvelopper les scripts
entirement par vous-mme laide de ces indices et de la documentation officielle avant
de regarder la solution propose. Si vous faites cet effort, vous matriserez le logiciel et le
langage beaucoup plus vite que si vous vous contentez de recopier mon code.
Pour toute remarque, suggestion, question, vous pouvez me contacter via mon site web
http://anthony-cardinale.fr.
Il ne me reste plus qu vous souhaiter une bonne lecture !

4. Rglage de la largeur de lcran


Vous trouverez de nombreux exemples de code, formats dans une police chasse fixe.
Afin dviter des retours la ligne inopportuns lintrieur dune ligne de code, la
longueur maximale des lignes de code a t fixe 65 caractres, une valeur suffisamment
basse pour tre affiche sur la plupart des supports, tout en tant suffisante pour que le
code puisse tre correctement format.
Toutefois, il est possible que sur votre support la largeur maximale affichable soit
infrieure la limite fixe. Le paragraphe test ci-dessous permet de vrifier votre
affichage. Il doit tenir sur deux lignes exactement :
00000000001111111111222222222233333333334444444444555555555566666
01234567890123456789012345678901234567890123456789012345678901234

Si ce nest pas le cas, regardez si vous pouvez agrandir la taille de la fentre, diminuer la
taille des marges ou diminuer la taille de la police daffichage. Sur un tlphone portable,
placez-le plutt en mode paysage. Si vous ny arrivez pas, ne vous inquitez pas pour
autant, la plupart des lignes de code sont infrieures 65 caractres.

5. URL raccourcies
Dans un souci de lisibilit, et pour pouvoir les maintenir jour, nous avons pris le parti de
remplacer toutes les adresses internet par ce quon appelle des URL raccourcies. Une fois
que vous avez accd la page cible, nous vous invitons lenregistrer avec un marque-
page si vous souhaitez y revenir frquemment. Vous disposerez alors du lien direct. Si
celui-ci se prime, nhsitez pas repasser par lURL raccourcie. Si cette dernire aussi
choue, vous pouvez nous le signaler !
1
Notions fondamentales du rseau
Un jeu multijoueur en ligne est sensiblement diffrent des autres types de jeux que nous
pouvons rencontrer. En effet, plusieurs joueurs sont runis dans un mme monde et
peuvent voluer ensemble. Pour que cela fonctionne, ils doivent avoir un accs internet et
tre connects au serveur qui se charge de synchroniser les donnes de chacun. Un jeu en
local ne demande ni connexion internet ni connexion un serveur, il est plus simple
coder car vous navez pas besoin de programmer les fonctionnalits lies au rseau. Unity
propose partir de la version 5.1 une API appele UNET pour Unity Networking qui
fournit de nombreuses fonctions trs pratiques pour programmer tous ces aspects.
Dans ce chapitre, nous allons essayer de comprendre ce qui se passe dans les coulisses
dun jeu en rseau. Cela vous aidera mieux aborder ce livre et le dveloppement de jeux
destins tre mis en rseau. Nous allons passer en revue les principales notions
matriser et expliquer les termes techniques que nous allons employer.
1. La notion de client/serveur
Un serveur est une machine sur laquelle les clients peuvent se connecter afin de
transmettre des donnes. Les clients (les joueurs) peuvent communiquer avec tous les
autres clients via le serveur. La Figure 1.1 vous aidera mieux comprendre comment la
communication est mise en place.
Figure 1.1 : Architecture client/serveur

Sur ce schma, nous pouvons voir que les joueurs (les clients) se connectent au serveur. Le
serveur transmet les informations aux clients comme par exemple la position de chaque
joueur et cela permet aux utilisateurs de jouer ensemble sur une mme carte.
Pour se connecter au serveur, les clients ont besoin de son IP. Ladresse IP (Internet
Protocol) est un numro didentification unique attribu un appareil en fonction du point
daccs partir duquel il est connect Internet. Connatre ladresse IP du serveur nous
permet dacheminer des donnes (des paquets) jusqu lui. Le paquet est une unit
informatique et les donnes sont dcoupes en paquets. Vous pouvez comparer cela un
facteur qui a besoin dune adresse pour livrer un colis ou encore un tlphone qui a
besoin dun numro pour tablir une communication.
Note > Le serveur a un rle trs important car cest lui qui va centraliser toutes les
informations concernant les joueurs connects et les informer en temps rel de ltat du
jeu pour quils puissent voir sur leur ordinateur ce qui se passe dans la scne. En dautres
termes, lorsquun joueur se dplace, le serveur enregistre le mouvement et le rpercute sur
les crans des autres joueurs.
2. Les protocoles de communication
Pour communiquer sur un rseau, il existe deux principaux protocoles :

TCP
UDP

Le protocole TCP/IP est un protocole qui va sassurer que toutes les donnes envoyes
sont bien arrives destination et dans lordre. Le protocole UDP permet denvoyer des
donnes sans quil ny ait de vrification au niveau de la bonne rception de ces donnes.
Le protocole UDP est donc moins strict que TCP.
En gnral, dans le jeu vido, le protocole UDP est utilis. En effet, dnormes quantits
de donnes sont transmises sur le rseau chaque seconde. Si un instant t un paquet se
perd, cela ne se verra pas. Par exemple si la position dun joueur nest pas envoye, on sait
que quelques millisecondes plus tard un autre paquet va tre envoy. Le laps de temps
entre lenvoi de deux paquets est tellement faible que cela nest pas perceptible par le
joueur.
Ce protocole permet au joueur de transmettre sa position au serveur et lorsque le serveur
reoit la nouvelle position du joueur, il informe tous les autres clients que tel ou tel joueur
sest dplac et tous les clients mettront jour la position du joueur qui sest dplac.
Note > Il existe bien sr dautres protocoles de communication trs connus comme ICMP
mais, dans le cas dun jeu vido, nous allons nous orienter vers le protocole plus optimis
pour de la 3D en temps rel. UDP ne grant pas les erreurs, les donnes qui transitent sur
le rseau sont un peu moins nombreuses et ainsi le jeu sera plus fluide. Les protocoles
grant les erreurs comme TCP sont trs utiles mais ils sont utiliss dans dautres cas
comme par exemple un chat car sil manque un mot dans une phrase, elle perdra son sens,
il faut donc contrler que les donnes ont bien t reues et dans le bon ordre sinon
lutilisateur n2 ne comprendra pas votre message. Dans un jeu vido, les informations
sont mises jour environ 60 fois par seconde, il nest donc pas ncessaire de vrifier les
donnes car une petite erreur ne sera jamais visible.
3. Le systme de host
Les serveurs de jeux sont des machines permettant de grer les clients pour leur permettre
de jouer ensemble. Cest ce que nous avons vu ci-dessus. Cependant, ce nest pas tout le
monde qui peut se permettre dacheter ou de louer un serveur, car cela cote trs cher. Les
gros jeux comme World of Warcraft ont besoin de plusieurs salles remplies de serveurs qui
tournent 24h/24, 365 jours par an. Cette architecture cote trs cher et ces salles sont
climatises en permanence. Nous nallons donc pas utiliser ce systme pour crer des jeux
en rseau.
Pour permettre plusieurs joueurs de jouer simultanment un mme jeu, nous allons
recourir la technique du host, qui est utilise par exemple dans les jeux de type Call of
Duty. Lorsque lon parle de host, il ny a pas de serveur proprement parler. En effet, un
host est un joueur qui prend le rle de serveur. Il cre la partie et accepte de donner son IP
aux autres participants. Dans cette configuration, les joueurs se connecteront celui
dentre eux qui a ce rle et cest lui (lhte) qui aura pour mission de grer la transaction
des donnes entre les clients comme le montre la Figure 1.2.
Figure 1.2 : Le systme dhost

Lhost est donc la fois joueur et serveur. Cette mthode est trs simple mettre en place
et elle est gratuite (vous navez pas besoin dune salle de serveurs).
Elle a cependant quelques limites : le nombre de joueurs connects simultanment est
restreint. Si celui-ci est trop lev, le jeu tournera au ralenti cest pourquoi vous devez
limiter le nombre maximum de joueurs par partie. Vous pouvez par exemple crer
plusieurs parties avec 24 joueurs.
Tableau 1.1 : Liste des parties cres

Nom de la partie Nombre de joueurs IP du serveur Action


Salle 1 18/24 127.0.15.23 Se connecter
Salle 2 24/24 192.168.0.1
Salle 3 01/24 128.12.54.10 Se connecter
4. Linterpolation
Une autre notion importante lorsquon parle de jeux en rseau, cest linterpolation. Il est
important de toujours bien optimiser un jeu en rseau afin dviter les ralentissements. De
petites astuces permettent de tricher pour envoyer moins dinformations sur le rseau.
Prenons lexemple dun personnage qui marche dun point A un point B. Si le jeu tourne
en 60 images par seconde, la position de ce joueur sera envoye sur le rseau 60 fois par
seconde, ce qui est norme. Afin de diminuer le nombre de donnes, nous allons passer
par linterpolation. Cette technique permet de nenvoyer que les positions respectant
certaines conditions prdfinies (par exemple, si le personnage sest dplac de plus de dix
centimtres). Les positions intermdiaires sont ensuite recres par interpolation.
Nous aurons donc lancienne position et la nouvelle position (dplacement de 10
centimtres) et pour obtenir un mouvement fluide, nous allons crer une transition entre
lancienne position et la nouvelle position. Dans cet exemple, cela vite denvoyer la
position du personnage chaque centimtre. Ce sera plus clair pour vous lorsque nous
entamerons le chapitre Optimisation pour le rseau.

5. Le principe dautorit (Authority)


Cette notion permet au dveloppeur de savoir qui a le droit de contrler quoi et qui
appartient tel ou tel GameObject. La proprit hasAuthority permet de dterminer si un
joueur est autoris ou non raliser une action. Par exemple, vous ne pouvez dplacer que
votre personnage avec les flches du clavier. Si vous tirez un projectile, celui-ci appartient
votre personnage. Cela permet donc de donner (ou pas) des autorisations aux joueurs.
Les clients peuvent aussi demander au serveur dexcuter des fonctions, par exemple
dplacer le personnage, et le serveur leur accordera ou non lautorisation de le faire. Cest
un moyen dviter que les joueurs ne trichent en passant par le serveur pour excuter leurs
actions.

Dans ce chapitre, vous avez vu :

ce quest une architecture client/serveur ;


comment fonctionne un systme avec un host ;
les protocoles de communication les plus courants ;
ce quest linterpolation ;
la notion dauthoritative.
2
Dcouverte dUNET
Avant larrive dUNET, les dveloppeurs Unity devaient tout coder de A Z lorsquil
sagissait de dvelopper un jeu en rseau. Ils devaient crer des scripts pour grer le
serveur, la connexion des clients, la synchronisation des lments sur les diffrents clients,
etc. UNET est un systme qui nous facilite grandement les choses et permet de mettre en
place trs rapidement un jeu multijoueur. La liaison client/serveur est automatique, de
mme que la synchronisation des lments, etc.
Unity a voulu frapper fort en proposant un outil trs puissant permettant tous les
dveloppeurs dinclure un mode en ligne dans leurs jeux. Bien sr, il y aura quand mme
du code crire mais ce travail sera beaucoup moins laborieux quauparavant. Dans ce
chapitre, je vais vous prsenter quelques-unes de ces fonctionnalits. Nous complterons
cette liste au fur et mesure des chapitres.
1. Le Network Manager
Bien que tous les composants dUNET soient importants, le Network Manager constitue
llment central dun jeu multijoueur. Cest le gestionnaire de rseau qui va grer toutes
les connexions clients/host et tous les paramtres du serveur. Il se charge, entre autres, de
connecter les clients au serveur via un port et une adresse IP, de crer les prefabs des
joueurs lorsque ceux-ci se connectent et de grer les dconnexions. Lorsquun objet est
instanci, il permettra son instanciation sur tous les clients connects au jeu. Voil quoi
ressemble ce composant :
Figure 2.1 : Aperu du Network Manager

Nous utiliserons galement un autre composant associ, il sagit du Network Manager


HUD, en dautres mots linterface utilisateur du Network Manager. Ce petit composant
trs simple permet de faire apparatre lcran un menu lmentaire pour crer un serveur
ou se connecter un serveur :
Figure 2.2 : Le Network Manager HUD

Nous y recourrons dans ce livre pour faire des tests rapides et vrifier que la mise en
rseau se fait bien.
Attention > Ce composant ne doit pas tre utilis en production, il ne sert qu tester votre
projet. Pour la version finale de notre jeu, nous dvelopperons notre propre menu avec les
seules fonctions qui nous intressent et une interface personnalise.
2. Le Network Identity
L aussi, il sagit dun composant extrmement important car cest lui qui va donner une
identit, donc une existence, aux objets qui doivent tre visibles sur tout le rseau comme
par exemple les personnages joueurs ou les projectiles. Pour quun objet puisse tre visible
ou instanci sur le rseau, il doit possder ce composant, qui lui attribuera un numro
unique.
Au-del de ces proprits essentielles, le Network Identity offre des possibilits trs
puissantes comme par exemple rcuprer lidentifiant unique dun objet, savoir si le
joueur en cours est client ou serveur, connatre les permissions selon le principe dautorit
ou encore de savoir quels objets peuvent voir tel ou tel autre objet. Nous examinerons cela
plus en dtails au cours des chapitres suivants car nous aurons besoin de savoir, par
exemple, qui a tir le projectile et qui a t touch par ce dernier pour faire le calcul des
points.

3. Le Network Transform
Comme son homologue le Transform, le Network Transform permet de grer des
informations relatives la position, la taille ou la rotation dun objet de jeu. Cependant, le
Network Transform a la capacit de synchroniser les mouvements dun GameObject
travers le rseau, cest--dire quil est capable de transmettre la position dun objet tous
les autres clients connects au rseau.
Les proprits de ce composant permettent de grer le mode de synchronisation ou encore
la quantit dinformations envoyes sur le rseau afin dallger le flux de donnes. Voil
quoi il ressemble :
Figure 2.3 : Le Network Transform

Note > Bien que ce composant soit configurable, il nest pas suffisamment optimis dans
certains cas. Nous verrons dans la suite de ce livre comment en programmer nous-mmes
les fonctionnalits tout en optimisant la synchronisation de la position des objets afin de
rduire les ralentissements et les bugs.
4. Quelques proprits bien utiles
Outre les composants prcits, UNET apporte une panoplie de nouvelles fonctions trs
utiles pour programmer des jeux en rseau. Nous aurons loccasion de les mettre en
pratique mais voici dj une petite liste des principales dentre elles :
isServer

Facile comprendre, cette fonction permet de tester si lobjet sur lequel est attach le
script tourne sur le serveur.
isClient

Il sagit de la fonction inverse et celle-ci permet de savoir si lobjet tourne sur un


client.
isLocalPlayer

Cette fonction, trs utile, permet de savoir si lobjet est un objet du joueur local.
netId

Correspond lidentifiant unique dun objet sur le rseau.


Spawn

Cest la fonction permettant dinstancier un objet sur le rseau afin quil soit visible
par tous les clients.

UNET apporte galement de nouvelles faons de dclarer des variables par exemple le
mot cl [SyncVar] permet de synchroniser automatiquement la valeur dune variable sur
le rseau. Le mot cl hook, quant lui, permet dexcuter une fonction lorsquune variable
en [SyncVar] est modifie. Cela permet de faire un traitement spcial si besoin. Dautre
part, certains mots cls permettent dexcuter des fonctions dune faon bien prcise sur le
rseau. Par exemple :
[Server]

Une fonction prcde du mot [Server] ne sexcutera que sur le serveur.


[Client]

Une fonction prcde du mot [Client] ne sexcutera que sur le client.


[Command]

Permet un client de demander au serveur dexcuter une fonction.


[ClientRpc]

Permet dexcuter une fonction sur tous les clients.

La liste donne ci-dessus nest pas complte, les proprits dUNET tant nombreuses,
mais elle prsente les fonctionnalits les plus couramment utilises. Avec ces dernires
vous serez en mesure de coder 90 % des fonctionnalits lies au rseau. Nous verrons dans
la suite de ce livre dautres proprits dont nous aurons besoin pour optimiser notre jeu.
Dans ce chapitre, vous avez pris connaissance avec les principaux composants et
fonctions dUNET, notamment :

le Network Manager ;
le Network Identity ;
le Network Transform ;
quelques fonctions permettant de localiser les objets sur le rseau ;
de nouveaux attributs proposs par UNET.
3
Mise en rseau
Notre travail nous a permis de crer un prototype de jeu trs simple mais fonctionnel. En
effet, nous pouvons nous dplacer dans le niveau et nous pouvons tirer avec notre arme.
Mme si notre jeu peut tre conserv ainsi, nous allons ajouter une couche rseau afin de
le rendre beaucoup plus intressant.
Nous allons voir maintenant comment ajouter un mode multijoueur en ligne un jeu dj
existant. Nous partirons du jeu 2D que nous avons dvelopp dans le module III.
Concevoir un jeu 2D. Si vous tes dj laise avec la conception de ce type de jeu, vous
navez pas besoin de le lire pour suivre ce qui suit. Il vous suffit de tlcharger les sources
de lexemple.
Nous allons avoir besoin dajouter de nouveaux composants qui nous permettront de
synchroniser en temps rel toutes les informations (position des personnages, des
projectiles) sur le rseau. Comme nous lavons vu au chapitre Notions fondamentales
du rseau, nous allons mettre en place un systme dhte. Le premier joueur lancer le jeu
aura le rle de serveur. Ce joueur pourra donner son IP ses adversaires afin que ceux-ci
puissent se connecter au jeu.
Note > Dans notre cas, le joueur qui aura le rle de serveur aura besoin de rcuprer son
IP et de la donner ses adversaires. Cette tape nest pas automatique. Pour automatiser
ce processus, il faut souscrire un service payant auprs de Unity. Dans la suite de ce
livre, vous apprendrez communiquer avec un serveur. Vous serez en mesure de crer un
petit systme qui rcuprera lIP de lhte, qui stockera cette IP en ligne afin
quautomatiquement les autres joueurs puissent la rcuprer. Cela vous permettra
dautomatiser cette tape de connexion lhte.
Dans le cadre de notre exemple, nous limiterons le nombre de joueurs maximum quatre
mais cela pourra tre adapt par la suite. Une fois connects, les joueurs pourront se tirer
dessus.
Nous allons utiliser un Network Manager pour grer la cration du serveur et la connexion
des clients. Pour le mettre en place, nous avons besoin dune online scene, le jeu, et dune
offline scene, le menu principal. Avant toute chose, nous devons donc crer un menu.
1. Cration du menu principal
Dans un premier temps, nous allons crer un menu extrmement simple qui ne nous
servira qu lancer le jeu. Crez une nouvelle scne (Ctrl+N) et enregistrez-la (Ctrl+S)
sous le nom Menu. Vous pouvez laisser cette scne vide ou y placer une image pour la
dcorer.
Une fois la scne prte, vous devez crer un objet vide (GameObject/CreateEmpty) et lui
ajouter le composant Network Manager (Component/Network/NetworkManager). Ajoutez
galement le Network Manager HUD (Component/Network/NetworkManagerHUD) pour
gnrer une interface utilisateur minimaliste.
Figure 3.1 : Les composants dUNET

Sans rien faire de plus, ces deux composants sont


suffisants pour grer une simple mise en rseau. Si
vous lancez le jeu, vous devriez avoir linterface
visuelle suivante sur votre menu :
Figure 3.2 : Le Network Manager HUD

Le premier bouton LAN Host permet de crer un serveur. Le deuxime LAN Client
permet de se connecter un serveur en spcifiant une IP dans le champ de texte droite du
bouton. Le troisime permet de crer un serveur sans tre client (utile lorsque vous voulez
crer une partie sur un ordinateur sans que lon puisse jouer partir de cet ordinateur). Le
dernier, enfin, permet de crer et de rejoindre des parties en ligne en passant par les
serveurs dUnity. Nous nutiliserons pas cette fonctionnalit qui est payante.
2. Configuration du Network Manager
Pour que le Network Manager puisse utiliser les scnes du jeu, elles doivent tre dclares
dans les Build Settings. Allez donc dans File/Build Settings et ajoutez-y les quelques
scnes qui constituent votre jeu.
Figure 3.3 : Ajout des scnes au Build Settings

Une fois les scnes dans les Build Settings, vous pouvez les ajouter au Network Manager
pour indiquer laquelle est la online scene et laquelle est la offline scene. Pour cela, il vous
suffit de les glisser/dposer dans la variable de linspector. Pour notre part, nous
choisissons le menu comme scne offline et le niveau 1 comme scne online.
Vous devez aussi spcifier quel est le prefab du personnage joueur qui doit tre instanci
lors de la connexion dun joueur. Ce prefab doit tre plac dans la variable Player Prefab
contenue dans les Spawn Info du Network Manager (voir Figure 3.6). Cependant, vous ne
pouvez pas associer nimporte quel prefab cette variable. En effet, pour tre visible sur le
rseau, un prefab doit imprativement possder un Network Identity. Le Network Identity
donne une existence un objet sur le rseau. Pour ajouter ce composant au prefab du
joueur, placez le joueur sur la scne et utilisez le menu Component/Network/Network
Identity.
Figure 3.4 : Les composants UNET

Pendant que nous y sommes, nous allons galement


ajouter un Network Transform notre personnage. Le
Network Transform est un composant qui va transmettre
la position de lobjet sur le rseau. Le seul paramtre
modifier est le Sync Mode afin de se mettre en mode
Sync Transform :
Figure 3.5 : Le Network Transform

Une fois que le personnage est configur pour le rseau, vous pouvez crer un prefab de
celui-ci ou tout simplement remplacer lancien prefab. Vous pourrez ensuite ajouter le
personnage au Network Manager :
Figure 3.6 : Configuration du Network Manager
Le nombre maximum de joueurs est quant lui accessible lorsque vous cochez la case
Advanced Configuration :
Figure 3.7 : Configuration avance

Compilez le jeu (Ctrl+B) pour pouvoir en lancer plusieurs instances. Afin de tester sa
partie rseau, vous devez crer le serveur dans une fentre et rejoindre le serveur en tant
que client dans une autre fentre ou directement dans Unity en lanant le projet. La mise
en rseau doit se faire. Si votre pare-feu vous demande une autorisation, acceptez-la.
Figure 3.8 : Pare-feu
La Figure 3.9 montre ce qui se passe lorsque vous crez un serveur et un client.
Figure 3.9 : Test du mode multijoueur

Comme vous pouvez le voir, les deux joueurs sont bien connects en mme temps sur une
mme scne. Si vous avez test le jeu, vous avez d remarquer quil y a un petit
problme En effet, les personnages ont exactement les mmes scripts ! Lorsque vous
vous dplacez avec le clavier, les deux personnages font exactement les mmes
mouvements et au mme moment car ils sont contrls par votre clavier. Voyons
maintenant comment faire en sorte que le joueur ne puisse contrler que son propre
personnage.
3. Contrle du personnage local
Le joueur ne doit pouvoir contrler que son personnage local, cest--dire le personnage
qui a t instanci dans sa fentre de jeu. Chaque personnage dispose dun script de
mouvement, qui teste si le joueur touche le clavier. Si tel est le cas, il dplace le
personnage. Pour linstant, le script sexcute que le personnage soit le vtre ou non. Nous
allons donc utiliser les fonctionnalits dUNET pour dsactiver le script si le personnage
ne vous appartient pas car vous ne devez pas pouvoir dplacer les personnages des autres.
La fonction isLocalPlayer permet de faire cela. Retournons donc dans le script Joueur
afin dy apporter les modifications ncessaires. Nous devons inclure les fonctions rseau
via linstruction using UnityEngine.Networking;. Nous devons galement faire driver
la classe Joueur de NetworkBehaviour au lieu de MonoBehaviour.
Note > NetworkBehaviour est similaire MonoBehaviour mais apporte les fonctionnalits
de rseau en plus. Si votre script utilise des fonctions lies UNET et au rseau, vous
devez driver de NetworkBehaviour au lieu de MonoBehaviour.
Nous pouvons maintenant utiliser les fonctions proposes par UNET. Nous allons
englober toute notre fonction FixedUpdate dans une condition if(isLocalPlayer) afin
de nexcuter les instructions que pour le joueur que nous contrlons. Voil le code du
script Joueur.cs mis jour :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Joueur : NetworkBehaviour {



public float vitesse = 7.0f;
private bool isJumping = false;
public GameObject viseur;
public GameObject bullet;

void FixedUpdate () {
if(isLocalPlayer)

{ if(Input.GetKey(KeyCode.Q) || Input.GetKey(KeyCode.LeftArrow)) {
transform.Translate(Vector2.left * vitesse * Time.deltaTime); transform.localScale = new
Vector3(-1,1,1); } else if(Input.GetKey(KeyCode.D) ||
Input.GetKey(KeyCode.RightArrow)) { transform.Translate(Vector2.right * vitesse *
Time.deltaTime); transform.localScale = new Vector3(1,1,1); }
if(Input.GetKeyDown(KeyCode.Space)) { if(!isJumping) { StartCoroutine(Jump()); } }
if(Input.GetMouseButtonDown(0)) { CmdFire(); } } } IEnumerator Jump() { isJumping =
true; GetComponent<Rigidbody2D>().AddForce(Vector2.up * 500); yield return new
WaitForSeconds(1.5f); isJumping = false; } void CmdFire() { GameObject go =
(GameObject)Instantiate(bullet, viseur.transform.position, Quaternion.identity);
go.GetComponent<Rigidbody2D>().AddForce((viseur.transform.position -
transform.position) * 250); } }
Condition pour dtecter si le personnage est celui du joueur ou non.

Les deux joueurs sont maintenant contrlables indpendamment par les joueurs qui ils
appartiennent.
Figure 3.10 : Mode multijoueur fonctionnel

Pensez galement, si vous le souhaitez (mais ce nest pas obligatoire), masquer le viseur
des personnages qui nappartiennent pas au joueur. Pour faire cela, je vous propose
dutiliser la fonction Start et la variable viseur : le viseur est masqu si la condition
if(!isLocalPlayer) est remplie. Voil ce que vous devez ajouter dans le script Joueur :

void Start()
{
if(!isLocalPlayer)
{
viseur.gameObject.GetComponent<SpriteRenderer>().enabled = false;
}
}

Note > Si le Sprite Renderer est dsactiv via linstruction enabled = false, le sprite ne sera
plus visible, cependant il sera toujours prsent dans le jeu sans que lon puisse le voir.
Cela peut vous permettre de masquer un objet tout en continuant lutiliser par exemple
pour instancier des objets sa position.
Ce que nous pouvons faire maintenant, cest modifier le prefab du personnage afin
dajouter une camra en tant quenfant. Jai donc plac la camra dans mon personnage en
0, 2, -10 pour quelle soit centre, lgrement au-dessus et en arrire. Voil quoi
ressemble le prefab de mon personnage :
Figure 3.11 : Le prefab du joueur

Pensez supprimer les camras qui se trouvent dans vos diffrents niveaux et enregistrer
votre prefab afin de garder en mmoire les nouveaux paramtres. Comme pour le viseur,
vous devez dtruire la camra qui ne vous appartient pas. Cette fois encore, nous pouvons
passer par une variable et la fonction Start. Voil le script Joueur :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Joueur : NetworkBehaviour {



public float vitesse = 7.0f;
private bool isJumping = false;
public GameObject viseur;
public GameObject camera; // La camra enfant du joueur
public GameObject bullet;

void Start()
{
if(!isLocalPlayer)
{
viseur.gameObject.GetComponent<SpriteRenderer>().enabled = false;
Destroy(camera.gameObject); // On dtruit la camra si ce n'est pas
notre joueur
}
}

void FixedUpdate () {
if(isLocalPlayer)
{
if(Input.GetKey(KeyCode.Q) || Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(Vector2.left * vitesse * Time.deltaTime);
transform.localScale = new Vector3(-1,1,1);
}

else if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(Vector2.right * vitesse * Time.deltaTime);
transform.localScale = new Vector3(1,1,1);
}

if(Input.GetKeyDown(KeyCode.Space))
{
if(!isJumping)
{
StartCoroutine(Jump());
}
}

if(Input.GetMouseButtonDown(0))
{
CmdFire();
}

}
}

IEnumerator Jump()
{
isJumping = true;
GetComponent<Rigidbody2D>().AddForce(Vector2.up * 500);
yield return new WaitForSeconds(1.0f);
isJumping = false;
}

void CmdFire()
{
GameObject go = (GameObject)Instantiate(bullet,
viseur.transform.position, Quaternion.identity);
go.GetComponent<Rigidbody2D>().AddForce((viseur.transform.position -
transform.position) * 250);
}
}

Pour tester la version modifie du jeu, vous devez le compiler une nouvelle fois avec
Ctrl+B. Voil le rsultat :
Figure 3.12 : Lancement du jeu en rseau
Chaque joueur est libre de ses mouvements, chaque joueur dispose de son propre viseur et
de sa propre camra. Nous avons donc spar le joueur local des autres clients.
Jusque-l nous avons bien avanc, notre projet semble fonctionnel cependant de
nombreuses choses sont encore amliorer. Les mouvements sont saccads, la position
des personnages nest pas correctement synchronise entre tous les joueurs, les projectiles
napparaissent pas sur les crans des autres joueurs Tous ces points ngatifs risquent de
perturber les joueurs, cest pourquoi nous allons rgler lensemble de ces problmes dans
les prochains chapitres.

Dans ce chapitre, nous avons :

cr un menu principal ;
mis en place le Network Manager ;
mis en place le mode multijoueur ;
modifi les scripts afin de les adapter au jeu en rseau.
4
Instanciation sur le rseau
Comme vous lavez certainement constat, lorsque vous tirez un projectile avec votre
arme, le projectile apparat bien sur votre cran mais il napparat pas sur les crans des
autres clients. Effectivement, les objets instancis par dfaut napparaissent pas sur le
rseau. Nous devons configurer le Network Manager pour pouvoir les instancier pendant
la partie.

1. Prparation du Network Manager


Tous les objets instanciables doivent imprativement tre enregistrs en tant que tel dans
la section Spawn Info du Network Manager. Cest l que nous avons, entre autres, dclar
le prefab du personnage qui doit tre cr pour les joueurs qui se connectent. Et cest l
que vous pouvez retrouver les Registered Spawnable prefabs qui sont en fait les prefabs
instanciables sur le rseau.
Figure 4.1 : Spawn Info

Pour ajouter un prefab instanciable, vous devez cliquer sur le petit plus (+) et faire glisser
le prefab instanciable, dans notre cas le projectile. Pour pouvoir tre enregistrs, les
prefabs doivent avoir un network identity et ventuellement un network transform pour
transmettre leur position. Nous allons donc ajouter ces composants notre prefab de
projectile :
Figure 4.2 : Les composants network

Pour la synchronisation du projectile sur le rseau, nous allons prfrer une


synchronisation du Rigidbody 2D car nous appliquons une force physique sur ce
composant. Notre projectile peut maintenant tre ajout aux prefabs instanciables.
Figure 4.3 : Ajout du prefab au Spawn Info

Maintenant, le Network Manager est prpar instancier cet objet sur lensemble des
clients mais il reste une tape importante avant que le systme ne fonctionne.
2. Utilisation de la fonction Spawn
Afin dinstancier le prefab sur le rseau, nous allons devoir demander au serveur
dindiquer tous les clients quun prefab a t instanci. Pour cela, nous allons utiliser la
fonction Spawn (dont le rle est prcisment de rendre possible linstanciation sur le
rseau) et le mot cl [Command] pour excuter la fonction sur le serveur.
cette fin, nous modifions le script Joueur et la fonction de tir. Le script drive de
NetworkBehaviour et inclut Networking, ainsi nous pouvons utiliser deux fonctionnalits
dUNET nous permettant dinstancier le prefab sur tout le rseau.
[Command]

void CmdFire() { GameObject go = (GameObject)Instantiate( bullet,


viseur.transform.position, Quaternion.identity); go.GetComponent<Rigidbody2D>
().AddForce( (viseur.transform.position - transform.position) * 250);
NetworkServer.Spawn(go); }

On ajoute le mot cl [Command] au-dessus de la fonction CmdFire. Elle sera donc


appele sur le serveur.

La fonction Spawn permet dindiquer que lobjet doit tre instanci sur tout le rseau.
Cest le serveur qui se charge ensuite de raliser cette opration. Elle transmet toutes
les informations concernant lobjet, comme par exemple la force physique qui lui a t
applique. Si lobjet instanci a t dclar dans les objets spawnables, cela
fonctionnera.

Vous pouvez tester le projet.


Nous devons passer par le serveur pour linstanciation car cest lui qui a les droits
dinstanciation sur le rseau, les clients peuvent simplement demander au serveur une
instanciation et cest le serveur qui la ralise.
Normalement chaque client doit voir les balles gnres par les autres joueurs, cependant
il reste quelques bugs puisque la position des personnages et des viseurs nest pas
synchronise sur tout le rseau, ce qui donne limpression que le client instancie sa balle
toujours au mme endroit mme sil se dplace. Nous allons corriger ce problme au
chapitre Optimisation pour le rseau en crivant notre propre script de synchronisation.

Dans ce chapitre, nous avons :

configur le Spawn Info du Network Manager ;


configur notre projectile ;
vu comment utiliser la fonction Spawn ;
utilis linstruction [Command].
5
Interactions entre joueurs
Dans ce chapitre, nous allons voir comment faire en sorte que lorsquun joueur est touch
par un projectile, lensemble des joueurs connects au jeu en soient informs
immdiatement. Cest ce que lon appelle la synchronisation sur le rseau. Par exemple, si
un personnage perd de la vie, tous les autres joueurs doivent pouvoir le voir. Vous
comprenez que cela permet dviter les bugs, par exemple un joueur ayant perdu doit
disparatre de tous les crans.

1. Synchronisation des variables


Tout dabord, examinons comment la synchronisation se passe en prenant par exemple la
vie des personnages. Ouvrez le script Vie et ajoutez Networking et drivez la classe de
NetworkBehaviour pour pouvoir utiliser les proprits dUNET, en loccurrence
[SyncVar].

using UnityEngine.Networking;
//
public class Vie : NetworkBehaviour
//

Nous allons placer la proprit [SyncVar] avant la variable vie de la faon suivante :
[SyncVar] public int vie = 3;

Cet attribut va servir synchroniser, cest--dire mettre jour la valeur de la variable sur
tout le rseau. Si le joueur perd un point de vie, tout le monde verra cette modification de
la valeur de la variable vie.
Note > Sachez que lattribut [SyncVar] est automatique. Lorsque la valeur change, SyncVar
fait son travail, mais vous pouvez passer par un systme de hook pour intervenir dans la
synchronisation. Par exemple, [SyncVar(hook="OnHealthChange")] signifie que lors du
changement de la valeur de la variable, une fonction OnHealthChange doit tre appele. Cette
dernire fonction peut ressembler cela :
void OnHealthChange(int v)
{
vie = v;
ModifiertextureVie();
}

Vous savez maintenant comment informer tous les joueurs de la valeur dune variable.
Nous allons maintenant passer un nouveau script qui sera attach au projectile et qui
servira diminuer la vie du joueur sil est touch.
2. Tirer sur les autres joueurs
Modifiez le script Bullet afin dajouter la couche rseau. Ce script doit pouvoir utiliser
UNET donc nous lui ajoutons Networking et NetworkBehaviour. Nous allons avoir besoin
dune variable de type uint (unsigned int = int positif) qui sera lID du joueur qui a
instanci ce prefab.
[SyncVar]
public uint idPlayer;

Le script contient principalement la fonction OnCollisionEnter2D permettant de dtecter


les collisions.
Dans cette fonction, nous allons dtruire le projectile et tester si un joueur a t touch via
un tag Player. Si un joueur a t touch, nous passerons par le serveur avec la fonction
isServer pour accder au script Vie de ce joueur, diminuer sa vie et tester sil est mort. Si
le joueur touch na plus de vie, nous incrmenterons le score de celui qui a tir le
projectile. LID du joueur qui a tir nous sera utile pour le retrouver parmi tous les autres
joueurs. Voil le code complet de Bullet.cs :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Bullet : NetworkBehaviour {

[SyncVar]
public uint idPlayer;

void OnCollisionEnter2D(Collision2D col)


{
Destroy(this.gameObject);

if(col.gameObject.tag == "Player")
{
if(isServer)
{
Vie scriptVie = col.gameObject.GetComponent<Vie>();
if(scriptVie != null)
{
scriptVie.vie -= 1;
if(scriptVie.vie <= 0)
{
GameObject[] tmp = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject p in tmp)
{
NetworkIdentity id = p.GetComponent<NetworkIdentity>();
if(id != null && id.netId.Value == idPlayer)
{
p.GetComponent<Joueur>().score++;
}
}
}
}
}
}
}
}

Le script est facile comprendre avec les explications donnes plus haut. Le Network
Identity contient la variable netId qui est utilise ici pour identifier de faon unique
chaque joueur. Nous utilisons GetComponent pour accder aux diffrents scripts. Pour
linstant le script ne peut pas fonctionner. Vous devez encore ajouter une variable score au
script Joueur :
[SyncVar]public int score = 0;

Vous devez aussi modifier la fonction CmdFire() et lui ajouter linstruction suivante juste
avant le Spawn :
go.GetComponent<Bullet>().idPlayer = GetComponent<NetworkIdentity>
().netId.Value;

Cette instruction permet de modifier la valeur de la variable idPlayer du script Bullet du


projectile, ainsi le joueur qui tire est identifi comme le crateur de ce prefab. Voil la
fonction CmdFire avec la modification :
[Command]
void CmdFire()
{
GetComponent<AudioSource>().PlayOneShot(son);
GameObject go = (GameObject)Instantiate(bullet,
viseur.transform.position, Quaternion.identity);
go.GetComponent<Rigidbody2D>().AddForce((viseur.transform.position -
transform.position) * 250);
go.GetComponent<Bullet>().idPlayer = GetComponent<NetworkIdentity>
().netId.Value;
NetworkServer.Spawn(go);
}

Enfin, pour que la collision soit prise en compte, vous devez ajouter le tag Player au
prefab du personnage joueur :
Figure 5.1 : Ajout du tag au joueur

Vous pouvez tout enregistrer, compiler et tester votre jeu. Si vous crez deux instances du
jeu et que vous tirez sur un autre joueur, vous verrez que la valeur de vie sera modifie
dans le script et que la barre de vie est galement fonctionnelle. Si le joueur est touch, il
perd de la vie et cela se voit sur le rseau.
Le score est galement synchronis sur le rseau et le personnage explose bien lorsquil
na plus de vie. Actuellement le joueur est replac en position 0,0,0 avec trois points de
vie. Voil deux images reprsentant le fonctionnement des variables synchronises :
Figure 5.2 : Le jeu avec quatre joueurs

Figure 5.3 : Les barres de vies en action


Maintenant, il est facile pour un joueur de savoir sil a touch un autre personnage. Lors
dune collision, le personnage touch perd un cur et la barre de vie sanime.
Dans le chapitre suivant, nous allons faire de nombreuses optimisations pour amliorer le
confort des utilisateurs et la transmission des donnes.

Dans ce chapitre, nous avons vu comment :

synchroniser des variables sur le rseau ;


grer la collision des projectiles ;
diminuer la vie quand on est touch.
6
Optimisation pour le rseau
Dans ce chapitre, nous allons raliser des oprations doptimisation afin de rduire les lags
(temps de latence) et amliorer la fluidit gnrale de notre jeu. Nous allons amliorer la
synchronisation de la position des joueurs et de leur viseur sur le rseau et dtruire les
objets instancis pour limiter le nombre dinformations transmettre.
1. Cration dune fonction de synchronisation
de la position
Jusqu maintenant nous avons utilis le Network Transform pour transmettre la position
des joueurs sur le rseau. Nous nallons plus utiliser ce composant car nous allons
dvelopper notre propre script de transmission de position. Lavantage est que nous
pouvons coder celui-ci de faon tre performant sur le rseau, le dsavantage cest que
cela demande du dveloppement, cest donc plus complexe que dutiliser le Network
Transform.
Voyons donc comment dvelopper notre propre fonction de synchronisation de position.
Avant cela nous dsactivons le Network Transform qui se trouve sur notre personnage :
Figure 6.1 : Dsactivation du Network Transform

Ainsi ce composant ne sera plus utilis dans notre jeu. Vous pouvez ouvrir le script Joueur
car cest dans ce script que nous coderons la fonction qui va envoyer la position du
personnage local sur le rseau.
Cette partie nest pas trs complexe en soi mais il faut bien comprendre ce que nous allons
raliser. Au chapitre Notions fondamentales du rseau, nous avons vu la notion
dinterpolation, qui consiste crer par script une transition fluide entre un point A et un
point B pour simuler le mouvement dun objet. Cest ce que nous allons faire pour notre
personnage, nous allons transmettre sa position sur le rseau et crer une transitions fluide
pour le dplacer de A B. partir de deux informations (deux positions), nous crons une
multitude de positions intermdiaires qui assureront la continuit du mouvement.
Nous allons commencer par crer une fonction SendPosition qui sera excute ct
client. Cette fonction transmettra la position du joueur au serveur. Voil la fonction
SendPosition que vous pouvez placer dans le script Joueur :

[Client]
void SendPosition()
{
CmdSendMyPositionToServer(transform.position);
}

La proprit [Client] permet de dire que cette fonction est excute ct client. Nous
faisons appel ici une autre fonction CmdSendMyPositionToServer qui doit tre excute
ct serveur. Cette fonction va juste mettre jour la variable contenant la position du
joueur :
[Command]
void CmdSendMyPositionToServer(Vector2 pos)
{
SyncPos = pos;
}

[Command] indique que cela doit tre excut ct serveur. Cette fonction modifie une
variable que nous devons crer au dbut du script Joueur :
[SyncVar] Vector2 SyncPos;

Il sagira de la position du joueur qui sera synchronise sur le rseau grce la proprit
[SyncVar].

Enfin, nous devons appeler la fonction SendPosition dans notre fonction Fixedupdate.
Ajoutez donc SendPosition(); la fin de la fonction FixedUpdate avant la fermeture de
laccolade. Cet appel se fera par le joueur local, seul le joueur local sera capable denvoyer
sa propre position. Tout ceci fonctionnera merveille mais rien ne sera visible sur le
rseau. En effet, les autres joueurs ne vous verront pas bouger car nous navons pas cr la
fonction qui simule le mouvement du joueur.
Toujours dans la fonction FixedUpdate, juste aprs la fermeture de laccolade qui termine
la condition if(isLocalPlayer), nous allons ajouter un else. Ce else sera donc excut
sur tous les joueurs du rseau autre que le joueur local. Cest dans ce else que nous allons
crer le mouvement du personnage en le plaant lendroit o il doit se trouver grce la
variable SyncPos :
else
{
transform.position = Vector2.Lerp(transform.position, SyncPos,
Time.deltaTime * 10);
}

La fonction Lerp permet de crer une interpolation entre la position du joueur et la valeur
de SyncPos. Il y aura donc une transition du personnage de la position laquelle il se
trouve vers la position laquelle il est cens tre. Nous multiplions cela par
Time.deltaTime pour que le mouvement soit le mme chez tout le monde.

Vous pouvez galement ajouter une variable SyncRot, un paramtre float rot et une
ligne de plus dans le else afin de transmettre galement les informations concernant la
rotation de votre personnage. Pour vous aider, voici le script Joueur.cs au grand complet
avec nos nouvelles fonctions :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Joueur : NetworkBehaviour {



public float vitesse = 7.0f;
private bool isJumping = false;
public GameObject viseur;
public GameObject camera;
public GameObject bullet;
public AudioClip son;
[SyncVar]public int score = 0;
[SyncVar] Vector2 SyncPos;
[SyncVar] float SyncRot;

void Start()
{
if(!isLocalPlayer)
{
viseur.gameObject.GetComponent<SpriteRenderer>().enabled = false;
Destroy(camera.gameObject);
}
}

void FixedUpdate () {
if(isLocalPlayer)
{
if(Input.GetKey(KeyCode.Q) || Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(Vector2.left * vitesse * Time.deltaTime);
transform.localScale = new Vector3(-1,1,1);
}

else if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(Vector2.right * vitesse * Time.deltaTime);
transform.localScale = new Vector3(1,1,1);
}

if(Input.GetKeyDown(KeyCode.Space))
{
if(!isJumping)
{
StartCoroutine(Jump());
}
}

if(Input.GetMouseButtonDown(0))
{
CmdFire();
}

SendPosition();
}
else
{
transform.position = Vector2.Lerp(transform.position, SyncPos,
Time.deltaTime * 10);
transform.localScale = new Vector3(SyncRot, 1, 1);
}
}

IEnumerator Jump()
{
isJumping = true;
GetComponent<Rigidbody2D>().AddForce(Vector2.up * 500);
yield return new WaitForSeconds(1.0f);
isJumping = false;
}
[Command]
void CmdFire()
{
GetComponent<AudioSource>().PlayOneShot(son);
GameObject go = (GameObject)Instantiate(bullet,
viseur.transform.position, Quaternion.identity);
go.GetComponent<Rigidbody2D>().AddForce((viseur.transform.position -
transform.position) * 250);
go.GetComponent<Bullet>().idPlayer = GetComponent<NetworkIdentity>
().netId.Value;
Destroy(go, 5.0f);
NetworkServer.Spawn(go);
}

[Client]
void SendPosition()
{
CmdSendMyPositionToServer(transform.position, transform.localScale.x);
}

[Command]
void CmdSendMyPositionToServer(Vector2 pos, float rot)
{
SyncPos = pos;
SyncRot = rot;
}
}

Vous pouvez compiler et tester le projet. Vous allez remarquer une grande diffrence par
rapport ce que nous avions. Les mouvements seront fluides et transmis sur le rseau.
Cela permet aussi de corriger de nombreux bugs comme par exemple limpression que les
projectiles sont toujours tirs du mme point. Nous avons maintenant une bonne
synchronisation qui se fait et qui est beaucoup plus optimise.
Il est possible de faire la mme chose pour les projectiles mais nous ne le ferons pas dans
ce livre. La synchronisation du Rigidbody 2D se fait de faon suffisamment correcte avec
le Network Transform. Sachez juste cette manipulation peut se faire avec tous les objets.
Vous pouvez mme optimiser davantage encore le script en nappelant la fonction
SendPosition que lorsque le joueur est en mouvement. Actuellement, la fonction est
appele mme quand il est immobile, or cela peut tre aussi optimis simplement. Vous
pouvez par exemple passer par une variable oldPos afin de comparer lancienne position
la nouvelle et tester la distance laide dune fonction Distance (public static float
Distance(Vector2 a, Vector2 b);) pour savoir sil y a eu un mouvement et si tel est le
cas, alors vous appelez SendPosition.
Vous devez bien comprendre cette manipulation car ces notions sont essentielles pour les
jeux en rseau.
2. Synchronisation de la position du viseur
Si vous avez test votre jeu, vous avez certainement remarqu que la position du viseur
des joueurs nest pas toujours correctement synchronise. En effet, il y a certains conflits
et quelques bugs lorsque plusieurs joueurs sont connects au jeu. Les projectiles ne sont
pas toujours instancis au bon endroit.
Nous allons utiliser une technique qui va nous permettre denvoyer le projectile au bon
endroit dans tous les cas. Dans un premier temps, nous allons devoir dsactiver le script
Arme qui se trouve sur le curseur si celui-ci nappartient pas au joueur local sinon le
curseur sera contrl par tous les personnages. Si le script est actif, nimporte quel joueur
peut dplacer le curseur en bougeant la souris. Pour dsactiver le script Arme, vous devez
ajouter la ligne suivante viseur.gameObject.GetComponent<Arme>().enabled = false;
dans la fonction Start du script joueur :
void Start()
{
if(!isLocalPlayer)
{
viseur.gameObject.GetComponent<SpriteRenderer>().enabled = false;
viseur.gameObject.GetComponent<Arme>().enabled = false;
Destroy(camera.gameObject);
}
}

Ainsi le script Arme ne sera plus actif pour les autres personnages.
Note > Le ! signifie diffrent. Ici, !isLocalPlayer signifie Si diffrent de joueur local
alors. Le code entre accolade ne sexcutera donc que pour le joueur local.
Maintenant nous allons modifier la fonction de tir de ce script Joueur. Comme la fonction
est excute sur le serveur, le projectile actuellement est propuls dans la direction qui
correspond la position du joueur qui est le serveur. Cest--dire que cest le serveur qui
dcide de la direction du projectile. Or nous ne voulons pas cela ! Cest le joueur local qui
doit donner la trajectoire de son projectile.
Supprimez le mot cl [Command] qui se trouve au-dessus de la fonction CmdFire et
supprimez galement NetworkServer.Spawn(go);. La fonction CmdFire servira
uniquement crer le projectile et lui attribuer toutes ses proprits (direction par
exemple). Quant linstanciation du projectile sur le rseau, elle sera gre par une
nouvelle fonction, qui sera excute ct serveur et que nous appelerons CmdShootBullet.
Nous la crons juste aprs la fonction CmdFire.
[Command]
void CmdShootBullet(GameObject g)
{
NetworkServer.Spawn(g);
}

Cette fonction prend en paramtre un GameObject, qui est le projectile instancier sur le
rseau.
Vous pouvez maintenant appeler la fonction CmdShootBullet dans la fonction CmdFire :
void CmdFire()
{
GetComponent<AudioSource>().PlayOneShot(son);
GameObject go = (GameObject)Instantiate(bullet,
viseur.transform.position, Quaternion.identity);
go.GetComponent<Rigidbody2D>().AddForce((viseur.transform.position -
transform.position) * 250);
go.GetComponent<Bullet>().idPlayer = GetComponent<NetworkIdentity>
().netId.Value;
Destroy(go, 5.0f);
CmdShootBullet(go);
}

[Command]
void CmdShootBullet(GameObject g)
{
NetworkServer.Spawn(g);
}

Comme vous pouvez le voir, nous avons maintenant deux fonctions, une qui cre le
projectile avec ses proprits et une autre qui instancie le projectile sur le rseau avec
toutes ses proprits. Ainsi le serveur ne peut pas rentrer en conflit avec les proprits du
projectile !
3. Destruction des objets instancis
Les objets instancis sur le rseau comme nos projectiles sont des objets qui demandent
beaucoup de ressources. En effet, la position de chaque projectile doit tre transmise en
permanence sur le rseau et ces oprations sont lourdes. Actuellement, les joueurs peuvent
tirer une infinit de projectiles et ces projectiles ont une dure de vie illimite sils ne
rentrent pas en collision. Si 500 projectiles sont instancis, nous serons dans lobligation
denvoyer la position des 500 projectiles 60 fois par seconde sur tout le rseau. Vous
comprenez bien que cela est trop lourd pour tre viable.
Nous allons donc utiliser la fonction Destroy pour dtruire les projectiles cinq secondes
aprs leur instanciation. Ajoutez cela dans la fonction CmdFire juste avant le Spawn :
Destroy(go, 5.0f);

Ainsi les projectiles seront dtruits quoi quil arrive cinq secondes aprs leur apparition.
Afin de limiter le nombre dlments instancis sur le rseau, vous pouvez aussi mettre en
place un systme de chargeur. Par exemple, chaque joueur peut tirer dix projectiles et il
doit patienter trois secondes le temps de recharger. Ce temps dattente permettrait
dallger la scne. Ce systme peut tre ralis avec une variable int nbBalles = 10;
que vous diminuez nbBalles -= 1; lorsque le joueur tire.
Voil pour ce qui en est de loptimisation rseau. Limportant est de limiter la quantit
dinformations qui circulent sur le rseau afin davoir un jeu fluide. Notre jeu est
maintenant totalement fonctionnel ! Si vous voulez le tester avec des amis, vous pouvez le
compiler, le donner par cl USB ou via tlchargement, et communiquer votre IP (le
serveur !) afin que les autres joueurs puissent vous rejoindre.
Note > Il existe de nombreux sites gratuits qui vous donnent votre IP. Entrez simplement
What is my IP sur votre moteur de recherche et vous obtiendrez une flope de sites
proposant ce service.

Dans ce chapitre, nous avons vu comment :

coder la transmission de notre position sur le rseau ;


mettre en place linterpolation ;
empcher le serveur de modifier le comportement des objets instancis ;
dtruire des objets instancis.
7
Cration dun menu personnalis
Notre jeu tant maintenant un stade avanc de dveloppement, nous allons pouvoir nous
pencher sur le menu principal. Pour linstant, nous utilisons le simple HUD qui gnre
automatiquement un menu permettant de tester le mode multijoueur. Nous allons crer
notre propre menu avec le systme dUI et coder les fonctions de connexion au jeu.

1. Cration du menu
Commenons par crer le menu du jeu. Dsactivez le Network Manager HUD de la scne
Menu afin de nettoyer totalement linterface. Nous navons plus de menu. Notre nouveau
menu comprendra :

un titre
un bouton Crer le serveur ;
un bouton Connexion au serveur ;
un champ texte pour lIP du serveur ;
un bouton Obtenir mon IP.

Au chapitre suivant, nous y ajouterons un menu de slection de niveaux. Voici linterface


que vous devez raliser :
Figure 7.1 : Le menu principal du jeu
Pour crer ces lments, vous devez passer par le menu GameObject/UI. Jai utilis les
composants Text, Button, Panel et Input Field pour construire ce menu. Voil ce que
contient mon canvas :
Figure 7.2 : Les composants du menu

La seule proprit que jai modifie sur le canvas est le Canvas Scaler :
Figure 7.3 : Le canvas du menu

Cela permet dadapter la taille des lments en fonction de la taille de lcran. Positionnez
donc les boutons sur linterface, modifiez les textes, la taille et la couleur des lments
comme vous le souhaitez, mon menu est simplement un exemple. Une fois que vous avez
positionn les lments, vous pouvez crer un nouveau script Menu.
2. Cration du script Menu
Ouvrez le script pour coder les fonctions du menu. Ce script doit pouvoir utiliser UNET
(networking + networkbehaviour) et il ne contiendra quune variable de type Text :
public UnityEngine.UI.Text hostNameInput;

La fonction Start nous sera utile pour spcifier une IP par dfaut qui sera lIP de
lordinateur local (localhost ou encore 127.0.0.1). Pour jouer en ligne et se connecter
celle du serveur, il faudra modifier cette IP.
void Start()
{
hostNameInput.text = NetworkManager.singleton.networkAddress;
}

Note > Dans la fonction Start ci-dessus, hostNameInput correspond au champ de saisie dans
lequel lutilisateur peut renseigner lIP du serveur. Nous accdons au texte et nous
attribuons lIP locale par dfaut en passant par le Network Manager et lattribut
networkAddress. Si lutilisateur souhaite modifier lIP par dfaut, il lui suffit de saisir lIP de
son choix.
Nous allons crer quatre fonctions :

StartLocalGame : crer un serveur ;

JoinLocalGame : rejoindre une partie ;

GetMyIP : connatre son IP ;

Disconnect : se dconnecter pour quitter le jeu.

Pour chacune de ces fonctions nous allons accder aux fonctions du Network Manager. La
fonction JoinLocalGame vrifiera si nous avons spcifi une IP avant de nous connecter.
Voil le script complet contenant ces quatre fonctions :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Menu : MonoBehaviour {

public UnityEngine.UI.Text hostNameInput; void Start() { hostNameInput.text =


NetworkManager.singleton.networkAddress; } public void StartLocalGame() {
NetworkManager.singleton.StartHost(); // Crer le serveur } public void
JoinLocalGame() { if(hostNameInput.text != ) {
NetworkManager.singleton.networkAddress = hostNameInput.text; }
NetworkManager.singleton.StartClient(); // Crer un client } public void GetMyIP() {
Application.OpenURL(https://www.whatismyip.com/); // Connatre mon IP } public
void Disconect() { NetworkManager.singleton.StopClient(); // Se dconnecter } }
Nous utilisons MonoBehaviour car notre script naccdera pas directement aux
fonctions dUNET. Chaque fonction appellera une autre fonction en passant par le
Network Manager.

Le hostNameInput est un champ de texte dans lequel nous pouvons spcifier le nom de
lhte (ou son IP).

La fonction StartHost est accessible via linstruction


NetworkManager.singleton.StartHost();. Cette fonction permet de crer une partie
et davoir le rle dhte.

La fonction JoinLocalGame nous permet de nous connecter une partie existante. Si le


texte du champ hostNameInput est vide, nous remplaons celui-ci par le hostname par
dfaut.

Une fois que nous connaissons lIP du serveur, nous pouvons nous y connecter grce
la fonction StartClient.

Application.OpenURL nous permet douvrir une page internet. Ici je redirige le joueur
sur un site web qui affiche lIP de ce joueur afin de laider partager son IP avec les
autres joueurs qui veulent rejoindre la partie. Il existe de nombreux autres sites
proposant le mme service.

StopClient est la fonction permettant au joueur de se dconnecter du jeu. lappel de


cette fonction, le joueur est redirig vers le menu principal du jeu.

Note > Pour plus dinformations sur les fonctions utilises, consultez la documentation du
Network Manager. Vous y trouverez galement dautres qui pourront vous tre utiles.
3. Association des fonctions au menu
Nous allons maintenant lier les fonctions aux boutons correspondants du menu. Pour cela,
vous devez slectionner les boutons, ajouter le script Menu ces boutons. Lunique
variable du script prend en paramtre le texte du champ permettant au joueur dentrer une
IP ou un nom dhte (Input). :
Figure 7.4 : Association des fonctions au menu

Pour grer le clic du joueur, vous devez utiliser le composant Button (Script) de chaque
bouton. Cliquez sur le signe + dans la partie infrieure du composant pour pouvoir faire
glisser le GameObject possdant le script que vous souhaitez appeler lors du clic dans la
liste des vnements OnClick. Slectionnez ensuite la fonction du script que vous voulez
appeler quand le joueur clique sur le bouton.
Figure 7.5 : Gestion du clic
Rptez lopration pour chaque bouton. Associez chacun deux la fonction que vous
souhaitez les voir excuter. Voici les correspondances :

bouton CrerServeur => fonction StartLocalGame


bouton Connexion => fonction JoinLocalGame
bouton MonIP => fonction GetMyIP
Figure 7.6 : Ajout dune fonction un bouton

Maintenant, lorsque le joueur cliquera sur un bouton, la fonction que vous lui avez
associe sera excute.
Vous pouvez crer un serveur, crer un client ou rcuprer votre IP. Le menu apporte les
mmes fonctionnalits que le prcdent mais cette fois-ci, il est totalement personnalis et
vous pouvez ajouter les fonctionnalits de votre choix. La fonction Disconnect peut,
quant elle, tre aussi utilise dans le jeu si vous voulez donner la possibilit au joueur de
se dconnecter pour quitter la partie. Voil par exemple un bouton que jai cr dans mes
niveaux avec la fonction de dconnexion associe :
Figure 7.7 : Un bouton de dconnexion

Jai plac ce bouton en haut gauche de lcran. Le joueur a maintenant la possibilit de


quitter le jeu tout moment.
4. Afficher le score
Tant que nous sommes sur la partie interface de notre jeu, profitons-en pour ajouter un
simple texte en haut gauche de lcran qui affichera le score du joueur local. Ce score est
l juste titre informatif.
Figure 7.8 : Affichage du score

Ouvrez le script Joueur pour y ajouter les fonctionnalits ncessaires. Commencez par
inclure la bibliothque UI dans son en-tte :
using UnityEngine.UI;

Nous allons utiliser la fonction GameObject.Find() pour rcuprer le GameObject du


texte afin de modifier sa valeur. Comme vous pouvez le voir sur limage suivante, mon
texte a pour nom score :
Figure 7.9 : Le texte du score

Nous ajouterons donc dans la fonction FixedUpdate du script Joueur :


GameObject.Find("score").GetComponent<Text>().text = "Score : "+score;
Ainsi le texte sera modifi en fonction du score du joueur et celui-ci pourra voir le nombre
de joueurs quil a limins. Voil quoi ressemble linterface utilisateur avec ces
modifications :

Figure 7.10 : Linterface utilisateur (UI)

Cest tout pour le moment ! Dans le prochain chapitre nous allons enrichir ce menu dun
slecteur de niveaux.

Dans ce chapitre, nous avons vu comment :

crer un menu personnalis ;


coder les fonctions du menu avec UNET ;
crer une interface utilisateur dans le jeu.
8
Menu Options et modes de jeux
Dans ce chapitre, nous allons ajouter des options au menu principal de notre jeu afin que
le joueur puisse tre totalement autonome. Les joueurs doivent pouvoir choisir un niveau
lors de la cration dune partie. Nous devons leur proposer une interface simple qui ne
ncessite aucune connaissance technique. Ce que nous allons faire dans ce chapitre peut
vous permettre galement de crer des types de jeux diffrents (matchs par quipes,
chacun pour soi, pas de rapparition etc.).

1. Cration dun menu de slection des


niveaux
Nous allons enrichir notre menu principal dun slecteur de niveaux. Je vous propose de
crer un bloc dans lequel vous placerez des images reprsentant vos niveaux. Commencez
par crer un panel (GameObject/UI/Panel) que vous positionnerez droite de lcran.
lintrieur de ce panel, ajoutez des images (GameObject/UI/Image). Par exemple, si vous
avez quatre niveaux, crez des visuels pour ces quatre niveaux et des sprites de ces visuels
afin de les placer sur les quatre images que vous avez cres :
Figure 8.1 : Le nouveau menu principal du jeu

Ce nouveau panel est trs simple et il suffit juste de crer des petites images en mode
sprite pour les appliquer lobjet Image. Crez votre menu de slection de niveaux de la
faon que vous voulez. Dans le cas de notre jeu dexemple, comme nous navons que deux
niveaux, jai dupliqu les images pour combler le vide mais rien ne vous empche de votre
ct de crer quatre niveaux ou plus.
2. Script de slection du niveau
Nous allons maintenant crer un nouveau script qui permettra de slectionner le niveau sur
lequel nous souhaitons jouer. Linitiateur de la partie, qui prendra le rle de serveur, aura
pour mission de slectionner le niveau sur lequel les joueurs vont saffronter.
Crez un script SelectionNiveau et ouvrez-le. Celui-ci accdera la variable online-
Scene du Network Manager pour modifier le niveau slectionn. Ce script est trs simple,
cest pourquoi je vous le donne en entier directement :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class SelectionNiveau : NetworkBehaviour {

public string levelName;

public void SelectLevel()


{
NetworkManager.singleton.onlineScene = levelName;
}
}

Vous comprenez le principe : nous modifions la scne de lancement lors du clic sur une
des images. Pour fonctionner, toutes les scnes doivent avoir t pralablement ajoutes
aux build settings. Placez le script de slection du niveau sur toutes les images qui
reprsentent les niveaux. Ajoutez-leur galement le script bouton (Component/UI/Button)
pour les rendre cliquables.
Vous devez galement renseigner dans linspector la valeur de la variable Level Name qui
correspond au nom du niveau qui doit tre charg. Par exemple, sur la premire image,
indiquez Niveau1 qui est le nom de la scne du niveau 1.
Figure 8.2 : Configuration des images

Maintenant que les boutons sont prts, nous pouvons grer lvnement clic. Comme la
Section 3, Association des fonctions au menu, vous devez cliquer sur le signe + dans la
zone OnClick du bouton afin dy glisser-dposer limage elle-mme pour pouvoir accder
la fonction SelectLevel.
Figure 8.3 : Gestion du clic

Faites cela pour chaque image reprsentant vos niveaux. Ainsi chaque image permettra la
modification du niveau de lancement lors du clic de lutilisateur.
Comme notre script utilise les fonctions du rseau, il se peut quUNET ajoute
automatiquement un Network Identity vos images. Si tel est le cas, un problme va
survenir : vos images seront dsactives au lancement de la scne. En effet, les objets
ayant un Network Identity ne sont pas visibles si vous ntes pas connect. Nous allons
donc crire un petit script, que nous appellerons ActiverImages, pour corriger ce
problme. Il aura une variable contenant les images et une boucle foreach qui nous
permettra de toutes les activer une une.
Voici le contenu de ce script :
using UnityEngine;
using System.Collections;

public class ActiverImages : MonoBehaviour {

public GameObject[] images;

void Start () {
foreach(GameObject go in images)
{
go.SetActive(true);
}
}
}

Placez-le sur le menu, par exemple sur la camra, et ajoutez toutes les images de vos
niveaux dans le tableau.
Figure 8.4 : Configuration du script

Ce script ractivera toutes les images qui ont t dsactives par le Network Identity. Cette
petite astuce savre utile dans ce cas et ne nous demande pas trop de temps de
dveloppement.
Vous pouvez tester notre nouvelle fonctionnalit. Choisissez un niveau et crez le serveur
pour voir si la slection du niveau se fait convenablement. Dans mon cas, aprs avoir
cliqu sur le niveau 2, jai cr un serveur et le niveau 2 a bien t charg. Vous pouvez
voir en direct la modification de la Online Scene en examinant le Network Manager.
Ce que vous pouvez faire galement, cest crer un texte indiquant le niveau qui a t
slectionn afin dinformer le joueur sur quel niveau il va jouer. Lors du clic, vous
modifiez le texte comme cela : Niveau slectionn : Niveau 2. Le joueur sera ainsi
inform que son action a bien t prise en compte (cest l un exemple de feedback).
Vous pouvez galement utiliser cette technique pour crer des modes de jeux, par exemple
un mode Joueur contre joueur et un mode Joueurs contre zombies. Je vous invite crer
des scnes diffrentes pour mettre en place ces modes de jeux.
3. Configuration du nombre de joueurs
Nous allons terminer notre menu de configuration en donnant la possibilit linitiateur de
la partie de dfinir le nombre maximum de joueurs. Pour cela, nous utiliserons un slider
(curseur).
Commencez par crer un slider ainsi quun texte qui servira afficher le nombre de
joueurs laide du menu GameObject/UI/.
Figure 8.5 : Mise en place du slider

Placez-le o vous voulez sur votre menu. Configurez-le : pour ma part, jai fix le nombre
de joueurs entre 2 et 4 (champs Min Value et Max Value) et tel quil soit un nombre entier
(case Whole Numbers coche) [cest donc un int].
Figure 8.6 : Paramtres du slider
Nous pouvons modifier le script SelectionNiveau (pour ne pas en crer un nouveau) et y
ajouter la fonction qui va permettre de dfinir le nombre de joueurs. Nous devons inclure
UnityEngine.UI pour utiliser ses fonctionnalits.

using UnityEngine.UI;

Nous crons une nouvelle fonction qui va modifier la variable maxConnections du


Network Manager. Elle se chargera galement de mettre le texte du slider jour. Jai
nomm celui-ci nbJoueurs pour pouvoir y accder via un GameObject.Find() :
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class SelectionNiveau : NetworkBehaviour {

public string levelName;

public void SelectLevel()


{
NetworkManager.singleton.onlineScene = levelName;
}

public void SetNbJoueurs()


{
NetworkManager.singleton.maxConnections =
(int)GetComponent<Slider>().value;
GameObject.Find("nbJoueurs").GetComponent<Text>().text =
"Nombre de joueurs : " + (int)GetComponent<Slider>().value;
}
}

Ajoutez ce script au slider pour grer lvnement On Value Changed et slectionnez la


fonction SetNbJoueurs.
Figure 8.7 : Association du script au slider

Comme un Network Identity a t ajout au slider, pensez lajouter au tableau des


GameObjects activer au lancement du jeu. Vous pouvez tester ces nouvelles
fonctionnalits afin de voir que votre menu est complet et fonctionnel !
Figure 8.8 : Le menu principal final

Voil quoi ressemble le menu dans ltat actuel des choses. Les joueurs seront en mesure
de configurer les parties avant de les lancer sans avoir de connaissances techniques en
programmation. Nhsitez pas leur donner encore plus de possibilits et leur permettre
de paramtrer librement le jeu avant de jouer.

Dans ce chapitre, nous avons vu comment :

crer une fonction de slection du niveau ;


coder un slider permettant de dfinir le nombre de joueurs ;
donner la possibilit au joueur de configurer le jeu sa guise.
9
Utilisation dune base de donnes
Il est difficile de parler de jeux multijoueurs en ligne sans parler des bases de donnes. Les
bases de donnes sont partout. Elles permettent de stocker des informations en ligne et dy
accder de nimporte o (mobile, navigateur, application, logiciel etc.).
Note > Les bases de donnes permettent non seulement de sauvegarder des donnes en
ligne pour pouvoir y accder de nimporte o mais aussi davoir le contrle sur ces
donnes afin de vrifier que les joueurs ne trichent pas.
Dans ce chapitre et dans les suivants, je vais vous montrer comment utiliser une base de
donnes afin denregistrer des informations en ligne. Nous allons par exemple stocker le
score ou encore les identifiants des joueurs en rseau.
Pour raliser toutes ces oprations, nous utiliserons certains langages bien connus dans le
monde du Web et je partirai du principe que vous en avez quelques notions, notamment en
PHP.
Note > Vous ne pourrez pas viter certains langages de programmation si vous crez des
jeux en ligne. Le PHP vous permettra de faire des traitements sur votre serveur, le SQL
dinterroger votre base de donnes, le JSON de formater des donnes, etc. Vous navez
pas besoin davoir des connaissances pousses dans ces langages mais vous devez en
possder au moins les bases pour comprendre les scripts et pouvoir les adapter vos
projets.
1. Les outils que nous allons utiliser
Pour utiliser une base de donnes, nous allons avoir besoin doutils autres que le logiciel
Unity. Il vous faudra bien sr une base de donnes et donc un serveur que vous pouvez
louer chez un hbergeur comme OVH ou 1&1. Leurs offres commencent 2 par mois. Si
vous ne souhaitez pas louer de serveur dans limmdiat mais que vous voulez raliser les
manipulations de ce chapitre, vous pouvez crer une base de donnes locale avec le
logiciel gratuit WampServer. Votre ordinateur agira alors comme sil tait un serveur.
Cest une solution parfaite pour sentraner et se former.
Note > Sous Mac OS, il existe le logiciel MAMP et sous Linux il sagit de LAMP. Ce sont
les mmes logiciels mais adapts aux systmes alternatifs Windows.
Nous allons galement devoir tudier des langages de programmation autres que le C#.
Nous ferons un peu de PHP, de SQL, de JSON et de HTML. Ces langages sont trs
populaires dans le monde du Web. Ils vont nous permettre de communiquer avec la base
de donnes et de formater les informations contenues dans cette base. Bien que ces
langages soient trs diffrents du C#, vous serez amen les utiliser pour vos projets.
Nous resterons sur des notions trs simples et tout le code source vous sera fourni. Vous
serez ainsi en mesure dadapter les scripts vos besoins mme si vous navez que
quelques notions.
Nous allons commencer par crer une simple base de donnes avec une table Score, qui
contiendra les scores des joueurs. Rendez-vous sur phpMyAdmin, linterface de gestion de
votre base de donnes. Si vous tes chez OVH, ladresse est la suivante :
https://phpmyadmin.ovh.net ; si vous tes en local avec Wamp, ladresse est :
http://localhost/phpMyAdmin/. Crez la table Score.
Figure 9.1 : Cration dune table dans la base

Et ajoutez les colonnes de cette table. Nous allons avoir besoin de trois colonnes (id,
pseudo, score) qui nous serviront sauvegarder les donnes qui nous intressent. Donnez
galement un nom votre table et paramtrez lid pour le dfinir comme cl primaire,
cest--dire une cl unique pour identifier la ligne.
Figure 9.2 : Prparation de la table
Nous pourrons utiliser cette table pour stocker les scores des joueurs en ligne et de faon
dfinitive. Vous pourrez mme crer un classement des meilleurs joueurs avec ce systme.
Pour vous connecter depuis le jeu la base de donnes, vous aurez besoin de vos
identifiants (pseudo, mot de passe, nom de la base et adresse de la base). Ces informations
vous sont donnes par votre hbergeur lors de votre commande. Si vous tes en local,
ladresse sera localhost, le pseudo sera root et il ny a pas de mot de passe si vous tes
sous Windows. Sous Mac le mot de passe est soit root soit toor. Pour les cas particuliers,
vous pouvez vous tourner vers Google, qui vous aidera trouver linformation dont vous
avez besoin. Lorsque votre base est prte, nous pouvons retourner dans Unity et prparer
les variables que nous allons envoyer en ligne.
2. Prparation des variables stocker en ligne
Dans un premier temps, nous allons stocker le score des joueurs en ligne. Le score
correspond au nombre de joueurs tus par le joueur local. Nous utiliserons les
PlayerPrefs pour conserver cette variable au fur et mesure des parties afin de toujours
garder sur le disque local ce score mme si le joueur quitte le jeu.
Dans un second temps, nous verrons comment faire en sorte que les autres joueurs
puissent connatre le score de chaque personne connecte la partie.
Retournez dans le script Bullet, qui est le script qui gre lattribution du score un
joueur. Nous allons utiliser les PlayerPrefs pour enregistrer ce score sur le disque dur du
joueur local. Pour enregistrer une variable sur le disque, vous devez crire :
PlayerPrefs.SetInt("cle", valeur);

Note > Linstruction PlayerPrefs enregistre une variable sur lordinateur local
uniquement et en aucun cas sur un serveur web.
Comme vous pouvez le voir, les Playerprefs sont des donnes stockes sous forme de
cl/valeur. Par exemple, vous pouvez avoir la structure suivante : le score qui a une valeur
de 5 est stock la cl "bestscore". Cest ce que nous allons faire pour grer le score du
joueur.
Nous allons mettre en place une petite condition qui va simplement tester si une valeur
existe dj en mmoire. Si cest le cas, on incrmente le score de 1, sinon on cre un score
de 1 en mmoire. Dans le script Bullet, ajoutez le bout de code suivant juste aprs
p.GetComponent<Joueur>().score++;.

if(PlayerPrefs.HasKey("bestscore"))
{
PlayerPrefs.SetInt("bestscore", PlayerPrefs.GetInt("bestscore") + 1);
}
else{
PlayerPrefs.SetInt("bestscore", 1);
}

Maintenant, le score sera stock dans la cl "bestscore". Si vous quittez le jeu, le score
sera toujours prsent sur votre disque, mme si vous teignez votre ordinateur. La
deuxime variable prparer est le pseudo du joueur qui a obtenu le score. Actuellement
les joueurs nont pas de pseudo car nous navons pas mis en place ce systme, cest
pourquoi les joueurs auront le nom suivant : Joueur suivi de lID unique attribu par le
Network Identity. Par script, le nom du joueur sobtient de la faon suivante :
String pseudo = "Joueur"+idPlayer ;

Maintenant que nous avons nos variables, nous pouvons prparer la fonction qui permettra
de stocker ces informations en ligne. Toujours dans le script Bullet, crez une nouvelle
fonction :
IEnumerator SaveScoreOnline(string pseudo)
{

IEnumerator est un mot cl qui, sil est plac devant le nom dune fonction, autorise
lemploi de linstruction yield permettant de mettre un script en pause. Cela nous
permettra de laisser le temps au script denvoyer les informations au serveur distant et de
continuer lexcution du script une fois les donnes transmises. En paramtre, nous
passons le pseudo du joueur qui a ralis le score que nous enregistrons.
La fonction SaveScoreOnline se chargera denvoyer ces variables (par exemple le score)
notre serveur en ligne. Vous pouvez lappeler comme cela :
StartCoroutine(SaveScoreOnline("Joueur"+idPlayer));

StartCoroutine nous permet dappeler (dexcuter) une fonction de type IEnumerator.


Vous ne pouvez pas appeler directement la fonction, vous devez utiliser StartCoroutine
dans ce cas prcis.
Bien sr cette fonction ne fait rien pour le moment mais nous allons arranger cela dans
quelques instants. Voil dj le script Bullet en entier :
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Bullet : NetworkBehaviour {

[SyncVar]
public uint idPlayer;
public int degats = 1;

void OnCollisionEnter2D(Collision2D col)


{
Destroy(this.gameObject);

if(col.gameObject.tag == "Player")
{
if(isServer)
{
Vie scriptVie = col.gameObject.GetComponent<Vie>();
if(scriptVie != null)
{
scriptVie.vie -= degats;
if(scriptVie.vie <= 0)
{
GameObject[] tmp = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject p in tmp)
{
NetworkIdentity id = p.GetComponent<NetworkIdentity>();
if(id != null && id.netId.Value == idPlayer)
{
p.GetComponent<Joueur>().score++;

if(PlayerPrefs.HasKey("bestscore"))
{
PlayerPrefs.SetInt("bestscore",
PlayerPrefs.GetInt("bestscore") + 1);
}
else{
PlayerPrefs.SetInt("bestscore", 1);
}

StartCoroutine(SaveScoreOnline("Joueur"+idPlayer));
}
}
}
}
}
}
}

IEnumerator SaveScoreOnline(string pseudo)


{

}
}
3. Envoyer des variables un script PHP
Le stockage des informations dans la base de donnes se fait en plusieurs tapes. Dans un
premier temps, nous envoyons les variables partir dun script C# (Unity) vers un script
PHP (serveur web). Dans un second temps, le script PHP va lire et vrifier les variables
avant de les insrer dans la base de donnes via une requte SQL. Le script PHP renverra
une rponse au script C# afin de savoir si tout sest bien pass ou non.
Dans cette section, nous allons voir comment envoyer des variables un script PHP. Pour
ceux qui ont dj cod en PHP, les variables seront transmises dans le tableau $_POST[] de
PHP. Nous allons utiliser la classe WWWForm de Unity pour grer la transmission des
donnes de C# vers PHP. Cette classe WWWForm permet de gnrer un formulaire (en
post) qui sera envoy un serveur web.
Nous devons commencer par crer une variable string qui contiendra ladresse URL du
script PHP en charge de grer les donnes. Le script sera par exemple plac sur
http://VotreSite.fr/VotreScript.php ou encore http://localhost/script.php.
Dans mon cas, le script PHP sera sur mon serveur http://anthony-cardinale.fr/ et
sappellera saveScore.php. Je dclarerai donc : private string url =
"http://www.anthony-cardinale.fr/saveScore.php";.

Maintenant que nous avons lURL, nous pouvons complter la fonction SaveScoreOnline
cre prcdemment. Pour crer un nouveau formulaire, vous devez crire cela :
WWWForm form = new WWWForm();

Pour ajouter des champs votre formulaire (des donnes), vous devez utiliser
form.AddField. Dans notre cas, nous avons deux informations ajouter :

form.AddField("pseudo", pseudo);
form.AddField("score", PlayerPrefs.GetInt("bestscore"));

Pour envoyer le formulaire lURL spcifie, nous devons crire :


WWW download = new WWW(url, form);

WWW est une autre classe qui permet daccder des pages web. Cette classe nous
permet aussi de tlcharger des donnes (texte, image, etc.) se trouvant sur un serveur via
une URL. Ensuite, il faut attendre la rponse du serveur afin de savoir si lenvoi a russi
ou chou :
yield return download;

Il ne nous reste plus qu vrifier que tout sest bien pass via la srie de vrifications
suivantes :
if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
if (download.text == "ok")
{
print ("OK");
// Les informations ont t enregistres dans la BDD
}
else
{
// Il y a probablement eu une erreur SQL
print ("PAS OK");
}
}

Ce qui nous donne le code complet suivant pour SaveScoreOnline :


IEnumerator SaveScoreOnline(string pseudo)
{
// Cration d'un formulaire avec envoi POST
WWWForm form = new WWWForm();
// Cration des champs du formulaire
form.AddField("pseudo", pseudo);
form.AddField("score", PlayerPrefs.GetInt("bestscore"));

// Envoi du formulaire
WWW download = new WWW(url, form);
// Attente de la rponse
yield return download;

if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
if (download.text == "ok")
{
print ("OK");
// Les informations ont t enregistres dans la BDD
}
else
{
// Il y a probablement eu une erreur SQL
print ("PAS OK");
}
}
}
4. Cration du script PHP de sauvegarde dans
la base
Nous pouvons maintenant crer le script PHP qui est appel par notre script C#. Une fois
cr, nous le placerons ladresse URL spcifie dans le script C# (variable url).
Dans le script PHP, vous devez spcifier les identifiants de votre base de donnes afin de
pouvoir vous y connecter. Voici comment le coder en PHP :
DEFINE("HOST", "localhost");
DEFINE("DBNAME", "NomDeLaBase");
DEFINE("USERNAME", "Identifiant");
DEFINE("PASS", "MotDePasse");
$bdd = new PDO('mysql:host='.HOST.';dbname='.DBNAME, USERNAME, PASS);

Remplacez les informations de connexion par vos identifiants. Pour rcuprer les variables
envoyes par le script C# nous procdons ainsi :
$pseudo = $_POST['pseudo'];
$score = $_POST['score'];

Jai donc rcupr mes deux variables. Nous pouvons maintenant crire une requte SQL
pour insrer ces donnes dans la base :
$sql = "INSERT INTO `u3d_scores` (`id`, `pseudo`, `score`) VALUES (NULL,
'".$pseudo."', '".$score."');";

Pour excuter la requte, nous faisons :


$result = $bdd->prepare($sql);
$result->execute();

La dernire tape consiste vrifier que tout sest bien pass et renvoyer linformation
au script C# :
$lastID = $bdd->lastInsertId();
if($lastID > 0){
echo "ok";
}
else {
echo "ko";
}

Voil le script PHP complet :


<?php
DEFINE("HOST", "localhost");
DEFINE("DBNAME", "NomDeLaBase");
DEFINE("USERNAME", "Identifiant");
DEFINE("PASS", "MotDePasse");

$bdd = new PDO('mysql:host='.HOST.';dbname='.DBNAME, USERNAME, PASS);
$pseudo = $_POST['pseudo'];
$score = $_POST['score'];

$sql = "INSERT INTO `u3d_scores` (`id`, `pseudo`, `score`) VALUES (NULL,


'".$pseudo."', '".$score."');";
$result = $bdd->prepare($sql);
$result->execute();

$lastID = $bdd->lastInsertId();
if($lastID > 0){
echo "ok";
}
else {
echo "ko";
}
?>

Si vous testez votre jeu, vous verrez que le score est bien enregistr dans la base de
donnes :
Figure 9.3 : Enregistrement du score dans la base

Dans notre exemple, une nouvelle ligne est cre chaque fois mais vous pouvez trs bien
crer une ligne unique par joueur. De plus, comme nous testons le jeu en local (les deux
joueurs sont sur le mme ordinateur), les deux joueurs partagent les mmes PlayerPrefs,
du coup ils ont le mme score mais ce score sera unique pour chaque joueur si chacun joue
sur un ordinateur diffrent.
Vous avez donc vu comment enregistrer des informations dans la base de donnes. Cette
mthode peut tre utilise dans tous les cas (cration dun compte joueur, enregistrement
des missions, enregistrement des statistiques etc.).
Dans ce chapitre, nous avons vu comment :

prparer une base de donnes pour notre jeu ;


appeler un script PHP via une fonction C# ;
insrer des donnes dans une base partir de Unity ;
utiliser les classes WWW et WWWform.
10
Cration dune API PHP
Aujourdhui, les API sont de plus en plus utilises. Une API est un service web permettant
dexcuter les actions CRUD (Create, Read, Update, Delete) cest--dire crer, lire, mettre
jour et supprimer des donnes dune base en appelant simplement une URL.
Les plus grands sites comme YouTube, Facebook, Twitter, etc. ont des API permettant aux
dveloppeurs daccder des fonctionnalits trs puissantes. Par exemple, YouTube
propose un service permettant de rcuprer les vidos dune playlist, qui sont alors
envoyes au format JSON (un format facile interprter). Un dveloppeur peut trs
facilement rcuprer ce JSON, qui est en ralit un simple texte, et lutiliser pour crer des
logiciels, applications mobiles ou sites. Les API peuvent tre utilises par nimporte qui et
avec nimporte quel langage de programmation.
Voil quoi ressemble le JSON :
Figure 10.1 : Exemple de chane JSON
Cette chane JSON provient dune API que jai dveloppe et qui retourne la liste de mes
tutoriels Unity. Sachez que jutilise le plug-in JSONview qui permet un affichage lisible
du JSON dans mon navigateur.
Ce texte peut tre rcupr par exemple en Java afin de crer une application mobile qui
affiche une liste de vidos. Il peut aussi tre rcupr par un site web qui afficherait ces
mmes vidos. Le principal intrt est de navoir quun seul code rutilisable partout et
facilement. Si vous mettez jour le JSON, tous les logiciels qui accdent ce JSON
seront aussi mis jour.
Dans notre cas, nous allons dvelopper une petite API qui nous permettra de crer un
compte utilisateur et de vrifier une connexion dun joueur. Cela vous fera une premire
approche et vous pourrez ensuite rutiliser ces techniques pour dautres projets et dautres
fonctions. Dans ce chapitre, nous dvelopperons donc principalement en PHP et nos
scripts devront tre placs sur un serveur web ou wamp.
Note > Les API ont non seulement lavantage dtre utilisables de nimporte o et via
nimporte quel langage de programmation mais elles sont aussi rapides lexcution (le
traitement est quasi instantan).
1. Prparation de la base de donnes
Comme expliqu prcdemment, nous allons mettre au point une API capable de crer un
utilisateur et de vrifier si un utilisateur existe grce au couple pseudo/mot de passe. Nous
allons donc crer une nouvelle table dans notre base, qui contiendra les utilisateurs. Nous
avons besoin dun ID, dun pseudo et dun mot de passe (pass). Dans phpMyAdmin, je
cre donc la table suivante :
Figure 10.2 : Prparation de la table Utilisateurs

LID sera la cl primaire et le couple pseudo/pass seront des varchar (chanes de


caractres) dune taille maximale de 255 caractres. Ma table aura pour nom u3d_users.
Jutiliserai le prfixe u3d_ pour toutes mes tables afin de ne pas les confondre avec les
autres tables de la base. Je vous conseille de toujours prfixer vos tables pour chaque
projet. Notre base est prte tre utilise, nous pouvons passer au code.
2. Cration de la classe Helper.php et des
fonctions
Nous allons commencer par crer un fichier Helper.php. Ce fichier sera utilis par tous
nos scripts et cest dans ce fichier que nous excuterons nos requtes SQL sur la base de
donnes. Cette classe sera la classe principale. Elle permettra galement de convertir le
texte en JSON.
Tout dabord, nous crons une premire fonction qui permettra de se connecter la base
de donnes comme nous lavons vu au chapitre prcdent :
<?php
DEFINE("HOST", "localhost");
DEFINE("DBNAME", "NomDeLaBase");
DEFINE("USERNAME", "Identifiant");
DEFINE("PASS", "MotDePasse");

class Helper {
function ConnectBDD(){
return new PDO('mysql:host='.HOST.';dbname='.DBNAME, USERNAME,
PASS);
}

}
?>

Ensuite nous ajouterons deux fonctions :

CreateUser : cration dun utilisateur avec un pseudo et un mot de passe ;

CheckConnection : vrification si un utilisateur existe dans la base.

function CreateUser($pseudo = null, $pass = null){


}
function CheckConnection($pseudo = null, $pass = null){
}

Ces deux fonctions prennent les deux mmes paramtres. La fonction CreateUser sera
assez complexe car nous allons devoir dans un premier temps vrifier les donnes
(pseudo/pass), puis vrifier si lutilisateur existe dj ou non pour ensuite linscrire sil
nexiste pas. Nous renverrons un message JSON pour indiquer si tout sest bien pass.
Pour se connecter la base, nous utilisons notre fonction :
$bdd = $this->ConnectBDD();

Ensuite, nous vrifions que nous avons bien reu des donnes et que le pseudo et le mot de
passe ne sont pas vides :
$mySqlData = array(
"pseudo" => (isset($pseudo) && $pseudo != "") ? strtolower($pseudo) :
null,
"pass" => (isset($pass) && $pass != "") ? strtolower($pass) : null,
);

Aprs nous crivons une petite requte, qui aura pour mission de rechercher si un
utilisateur avec le pseudo donn existe dans notre base :
$sql = "SELECT * FROM u3d_users WHERE pseudo = '".$mySqlData["pseudo"]."'";
$result = $bdd->prepare($sql);
$result->execute();
$d = $result->fetchAll(PDO::FETCH_ASSOC);

Ici nous stockons donc le rsultat de la requte dans une variable $d, cela signifie que si un
utilisateur existe, la variable $d ne sera pas vide. Si $d est vide alors nous pouvons insrer
un nouvel utilisateur avec les informations spcifies.
if(count($d) == 0){
$sql = "INSERT INTO u3d_users(";
foreach($mySqlData as $k => $v) if($v != null) $sql .= $k.",";
$sql = substr($sql, 0, strlen($sql) -1);
$sql .= ") VALUES(";
foreach($mySqlData as $k => $v) if($v != null) $sql .= "'".$v."',";
$sql = substr($sql, 0, strlen($sql) -1);
$sql .= ");";

$result = $bdd->prepare($sql);
$result->execute();
$lastID = $bdd->lastInsertId();

if($lastID > 0){
return json_encode(array(
"result" => true,
"msg" => "Utilisateur crer avec succs",
"id" => $lastID
));
}
else {
return json_encode(array(
"result" => false,
"msg" => "L'utilisateur n'a pas t inscrit",
));
}
}

Aprs avoir dcompos cette fonction CreateUser tape par tape, en voici le code
complet :
function CreateUser($pseudo = null, $pass = null){
$bdd = $this->ConnectBDD();

if($pseudo != null && $pass != null){

$mySqlData = array(
"pseudo" => (isset($pseudo) && $pseudo != "") ?
strtolower($pseudo) : null,
"pass" => (isset($pass) && $pass != "") ? strtolower($pass)
: null,
);

if($mySqlData["pseudo"] != null && $mySqlData["pass"] != null){
$sql = "SELECT * FROM u3d_users WHERE pseudo =
'".$mySqlData["pseudo"]."'";

$result = $bdd->prepare($sql);
$result->execute();
$d = $result->fetchAll(PDO::FETCH_ASSOC);

if(count($d) == 0){
$sql = "INSERT INTO u3d_users(";
foreach($mySqlData as $k => $v) if($v != null) $sql .=
$k.",";
$sql = substr($sql, 0, strlen($sql) -1);
$sql .= ") VALUES(";
foreach($mySqlData as $k => $v) if($v != null) $sql .=
"'".$v."',";
$sql = substr($sql, 0, strlen($sql) -1);
$sql .= ");";


$result = $bdd->prepare($sql);
$result->execute();
$lastID = $bdd->lastInsertId();

if($lastID > 0){
return json_encode(array(
"result" => true,
"msg" => "Utilisateur crer avec succs",
"id" => $lastID
));

}
else {
return json_encode(array(
"result" => false,
"msg" => "L'utilisateur n'a pas t inscrit",
));
}
}
} else {
return json_encode(array(
"result" => false,
"msg" => "Erreur des donnes saisies",
));
}

}

Pour pouvoir lutiliser en passant par une URL, nous devons crer un nouveau fichier
PHP. Nous lappellerons par exemple CreateUser.php. lintrieur de ce fichier, il faut
inclure la classe Helper.php et ensuite appeler sa fonction CreateUser en passant en
paramtre nos deux variables. Voil le code complet du script Createuser.php :
<?php require_once "Helper.php";
$helper = new Helper();

if(isset($_GET["pseudo"]) && isset($_GET["pass"])){

$pseudo = $_GET["pseudo"];
$pass = $_GET["pass"];

$helper->CreateUser($pseudo, $pass);
} else {
echo "Erreur, veuillez saisir tous les champs.";
}
?>

Lorsque les fichiers sont sur votre serveur, vous pouvez crer un utilisateur en appelant
lURL suivante : http://www.VotreSite.fr/CreateUser.php?
pseudo=utilisateur1&pass=123456. En appelant cette URL avec les variables passes en
$_GET, lutilisateur utilisateur1 sera cr et le mot de passe 123456 lui sera attribu.
Testez et regardez votre base de donnes, voil ce qui est apparu :
Figure 10.3 : Cration dun utilisateur avec lAPI PHP

Lutilisateur a bien t cr simplement en appelant lURL.


3. Cration de la fonction de connexion
Nous allons maintenant crer une nouvelle fonction dans le fichier Helper.php. Cette
fonction servira vrifier lexistence dun utilisateur dans notre base. Si lutilisateur
existe, nous allons renvoyer un tableau JSON avec son pseudo et son ID . Voil la fonction
CheckConnexion :

function CheckConnection($pseudo = null, $pass = null){


if($pseudo != null && $pass != null){
$bdd = $this->ConnectBDD();

$sql = "SELECT * FROM u3d_users WHERE pseudo='".$pseudo."' AND
pass='".$pass."'";

$result = $bdd->prepare($sql);
$result->execute();

$d = $result->fetchAll(PDO::FETCH_ASSOC);

return $this->ParseJson($d);
} else {
return null;
}
}

Comme vous pouvez le voir, nous appelons une fonction ParseJson qui va en fait servir
transformer le tableau PHP en chane JSON laide de la fonction PHP json_encode :
function ParseJson($array = array()){
$r = array();

foreach($array as $k => $v){
$t = array(
"id" => intval($v["id"]),
"pseudo" => (string)utf8_encode($v["pseudo"]),
);
array_push($r, $t);
}

$finalArray["utilisateur"] = $r;
return json_encode($finalArray);
}

Une fois encore, nous allons devoir crer un nouveau fichier PHP pour appeler ces
fonctions. Crez donc un fichier CheckConnection.php et ajoutez ce code lintrieur :
<?php require_once "Helper.php";
$helper = new Helper();

if(isset($_GET["pseudo"]) && isset($_GET["pass"])){
$pseudo = $_GET["pseudo"];
$pass = $_GET["pass"];
echo $helper->CheckConnection($pseudo, $pass);
}
?>

Vous pouvez tester cette nouvelle fonction. Voil ce que cela donne avec lURL suivante :
http://www.VotreSite.fr/CheckConnection.php?pseudo=utilisateur1&pass=123456

{
- utilisateur:[
- {
id: 1
pseudo: "utilisateur1"
}
]
}

Et voil ce que cela donne si jentre un mot de passe erron :

{
utilisateur: []
}

Notre API nous permet donc non seulement de crer un utilisateur mais aussi de vrifier si
un utilisateur existe en spcifiant un pseudo et un mot de passe. Cela peut notamment nous
servir crer un systme de cration de compte dans notre jeu et vrifier si lutilisateur a
entr ses bons identifiants avant de se connecter . Ainsi, avec ce que nous avons appris
dans le chapitre prcdent, vous serez en mesure de stocker dans une base de donnes
toutes les informations (argent, force, quipement, niveau) dun joueur et de les associer
son compte. En outre, avec cette API, vous pouvez galement crer un formulaire
HTML sur votre site web (si par exemple le jeu a un site web officiel) et les joueurs
pourront y crer un compte et se connecter partir du jeu. Un simple formulaire HTML
comme celui-ci peut suffire :
<form action=Createuser.php method=get>
<input type=text name=pseudo>
<input type=text name=pass>
<input type=submit>
</form>
4. Pour aller plus loin
Les studios de jeux ont souvent lhabitude de crer un site web pour chaque jeu publi.
Cela permet dune part de faire de la communication mais galement de grer les
utilisateurs. Vous pouvez par exemple concevoir un site avec un formulaire de
prinscription ou de prcommande afin que les internautes puissent ouvrir un compte.
Cela leur permettra de recevoir le lien de tlchargement du jeu mais galement dtre
dj inscrit dans la base de donnes. Ils pourront ainsi accder au jeu via leurs identifiants.
Vous pouvez enrichir votre API en ajoutant de nombreuses fonctions et sauvegarder
beaucoup de donnes. Si vous crez une version PC, une version mobile et une version
console de votre jeu, votre API vous servira envoyer les mmes donnes pour chaque
console, cest ce que les joueurs veulent : jouer depuis nimporte quel appareil et depuis
nimporte o tout en ayant accs toutes les donnes de son compte.
Vous pouvez crer une fonction SetScore et GetScore, une fonction GetMission ou
encore GetDefi. Cela peut vous permettre de proposer une qute par jour sans avoir
besoin de mettre jour votre jeu car votre jeu se contentera de faire appel votre API pour
rcuprer la mission du jour ! Les possibilits sont infinies et la technique est toujours la
mme.
Dans le prochain chapitre, vous allez dcouvrir comment accder votre API partir dun
script C# dans Unity.

Dans ce chapitre, nous avons vu comment :

crer des fonctions dans notre API ;


grer les paramtres en variable $_GET ;
utiliser notre API via nos URL ;
afficher une chane JSON lcran.
11
Utilisation de lAPI avec SimpleJSON
Comme nous lavons expliqu au chapitre prcdent, lintrt dune API est de pouvoir
tre appele et comprise par nimporte quel langage de programmation et partir de
nimporte quel logiciel ou appareil. Nous allons voir maintenant, dans le cadre de notre
projet, comment utiliser notre API dans Unity avec le langage C#.
Notre API ne nous renvoie pas beaucoup de JSON traiter, mais suffisamment pour
utiliser le plug-in SimpleJSON. Vous apprendrez ainsi lire du texte au format JSON, ce
qui vous servira pour vos gros projets de jeux. Et vous verrez par la mme occasion
comment utiliser un plug-in externe.
SimpleJSON est un script contenant des fonctions qui permettent de dcouper le JSON
reu afin de mieux le traiter et lafficher. Vous pouvez le tlcharger sur le wiki officiel de
Unity ou avec les sources de ce livre.
Pour intgrer SimpleJSON un projet, vous devez simplement placer le script dans un
dossier Plugins au niveau de la fentre de projet (voir Figure 11.1). Puis vous le dclarez
dans len-tte des scripts o vous souhaitez lutiliser laide de using SimpleJSON;.
Figure 11.1 : Plug-in SimpleJSON

Note > Le dossier Plugins doit tre plac la racine du projet pour tre pris en compte
par Unity comme tant le dossier contenant les plug-ins.
1. Cration dun compte joueur
Nous allons commencer par donner la possibilit aux joueurs de crer un compte pour
jouer au jeu et ainsi garder en mmoire des donnes qui seront stockes en ligne. Pour la
cration du compte utilisateur, nous allons passer par notre API et plus particulirement
par notre fonction CreateUser. cette tape, nous nutiliserons pas SimpleJSON ; le
plug-in interviendra la section suivante pour rcuprer et traiter les informations
renvoyes par notre script PHP.
Crez une nouvelle scne que vous appellerez Inscription. Cette scne contiendra un
petit formulaire trs simple avec deux champs de texte et un bouton Valider. Voil qui
ressemble mon formulaire :
Figure 11.2 : Formulaire dinscription

Ce formulaire permettra lutilisateur de choisir un pseudo et un mot de passe, puis de


cliquer sur valider pour crer un compte. Nous allons dvelopper un petit script pour grer
le formulaire et le clic sur le bouton valider. Crez un un nouveau script appel
Inscription et ouvrez-le. Ce script doit inclure les classes suivantes :

using SimpleJSON;
using UnityEngine.UI;

Nous allons avoir besoin de quatre variables. LURL de la page PHP de notre API, une
variable download de type WWW qui grera la rponse du serveur et deux variables
textes :
private string url = "http://www.VotreSite.fr/CreateUser.php";
private WWW download;
public Text pseudo;
public Text pass;

Nous allons maintenant crer une fonction qui appellera lURL que nous passerons en
paramtre. Cette URL sera modifie pour intgrer les variables pseudo et pass. Sa
structure ressemblera ceci : http://VotreSite.fr/CreateUser.php?
pseudo=VotrePseudo&pass=MotDePasse. Cela nous permettra de transmettre au script
PHP les informations relatives au pseudo et au mot de passe. Cette fonction demandera
lAPI de crer lutilisateur avec les informations spcifies. Nous pouvons crer une autre
fonction qui va simplement appeler la premire fonction :
public void CallFunction()

{ if(pseudo.text != && pass.text != ) { StartCoroutine(CreateUser()); } }


public IEnumerator CreateUser() { url = url+?
pseudo=+pseudo.text+&pass=+pass.text; download = new WWW(url); yield
return download; if ((!string.IsNullOrEmpty(download.error))) { print(Error
downloading: + download.error); } else { print (Ok); } }

Cette fonction nous servira appeler la fonction CreateUser.

Ce test nous permet de vrifier que le pseudo ainsi que le mot de passe ont bien t
renseigns.

StartCoroutine est linstruction qui nous permet dappeler une fonction de type
IEnumerator.

Cette fonction permet dappeler une URL afin denvoyer ou de recevoir des donnes
sous forme de texte. Ici nous allons appeler une URL en donnant un pseudo et un mot
de passe afin que le script PHP appel cre un utilisateur sur le serveur en ligne.

Il sagit de lURL que nous souhaitons appeler. Cette URL correspond au lien vers
notre fichier PHP et nous passons des variables (pseudo et pass) dans lURL.

La classe WWW nous permet dappeler lURL afin de rcuprer dans une variable la
chane de caractres renvoye par le serveur.

Linstruction yield nous permet dattendre le temps que le serveur termine son
traitement. Le script est en pause. Une fois que le traitement est termin, la fonction
continue de sexcuter.

Ce test nous permet de dtecter sil y a une erreur et si tel est le cas de lafficher dans la
console afin de pouvoir dbuger le programme.

Ce qui nous donne un script complet :


using UnityEngine;
using System.Collections;
using SimpleJSON;
using UnityEngine.UI;

public class Inscription : MonoBehaviour {

private string url = "http://www.VotreSite.fr/CreateUser.php";


private WWW download;
public Text pseudo;
public Text pass;

public void CallFunction()


{
if(pseudo.text != "" && pass.text != "")
{
StartCoroutine(CreateUser());
}
}

public IEnumerator CreateUser()


{
url = url+"?pseudo="+pseudo.text+"&pass="+pass.text;
download = new WWW(url);
yield return download;

if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
print ("Ok");
}
}
}

Nous ajoutons ce script au bouton valider et nous associons la fonction CallFunction


lvnement OnClick pour lappeler lors dun clic sur le bouton.
Figure 11.3 : Association de la fonction lvnement clic
Comme vous pouvez le voir, les deux variables textes nous permettent de faire glisser
(dans linspector) les objets Input correspondant au pseudo et au password. Ainsi le
contenu textuel de ces champs de saisie seront accessibles par le script. Cela nous permet
de rcuprer les chanes de caractres saisies par lutilisateur. Une fois que tout est prt,
vous pouvez tester votre scne :
Figure 11.4 : Test de linscription Figure 11.5 : La cration du compte est visible dans la base

Aprs avoir test, consultez votre base de donnes. Si tout sest bien droul, le compte
utilisateur doit avoir t cr. 'JHVSF)
2. Cration de la scne de connexion
Maintenant que les utilisateurs peuvent crer un compte, il faut leur donner la possibilit
de se connecter au jeu avec leurs identifiants. Ils entreront leur pseudo et leur mot de passe
pour se connecter, et sans que cela soit visible par eux , lAPI vrifiera si le couple
pseudo/pass correspond celui dun joueur. Si oui, le joueur sera connect au jeu avec son
profil. Vous pouvez crer une scne Connexion en reprenant le mme formulaire que celui
de la scne Inscription.
Crez un script Connexion et ouvrez-le. Ce script doit galement inclure les deux classes
et les quatre variables. Nous allons crer deux variables supplmentaires pour rcuprer et
traiter la chane JSON :
private string url = "http://www.VotreSite.fr/CheckConnection.php";
private WWW download;
public Text pseudo;
public Text pass;
private string monJson;
private JSONNode monNode;

La suite sera sensiblement la mme que pour linscription, la difrence prs que nous
utiliserons SimpleJSON pour afficher la chane de caractres retourne par lAPI :
monJson = download.text;

monNode = JSON.Parse(monJson); print (monNode[utilisateur][0]


[pseudo].Value) ;

Nous rcuprons le JSON renvoy par le serveur et nous le stockons dans la variable
monJson.

Nous utilisons la fonction JSON.Parse du plug-in afin de convertir le JSON en


chane lisible. Le rsultat est stock dans la variable monNode.

Nous affichons le pseudo de lutilisateur dans la console afin de vrifier que tout
fonctionne.

Comme le script est quasiment le mme, je vous le donne en entier :


using UnityEngine;
using System.Collections;
using SimpleJSON;
using UnityEngine.UI;

public class Connexion : MonoBehaviour {

private string url = "http://www.VotreSite.fr/CheckConnection.php";


private WWW download;
public Text pseudo;
public Text pass;
private string monJson;
private JSONNode monNode;

public void CallFunction()


{
if(pseudo.text != "" && pass.text != "")
{
StartCoroutine(CreateUser());
}
}

public IEnumerator CreateUser()


{
url = url+"?pseudo="+pseudo.text+"&pass="+pass.text;
download = new WWW(url);
yield return download;

if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
monJson = download.text;
monNode = JSON.Parse(monJson);
print (monNode["utilisateur"][0]["pseudo"].Value);
}
print (download.text);
}
}

Si le couple pseudo/mot de passe existe, vous verrez dans la console le nom du joueur qui
sest connect ainsi que toute la chane JSON qui a t retourne. Notre programme
communique bien avec le serveur et il affiche dans la console les informations renvoyes
par le serveur. Voil comment crer un systme de cration de compte et de connexion.
Vous pouvez stocker les informations donnes par lAPI dans des variables afin de les
utiliser dans le jeu. Par exemple vous pouvez afficher le nom du joueur, ses statistiques et
tous les objets quil possde.
Figure 11.6 : Appel de lAPI avec Unity et affichage du JSON dans la console

Le but de ce chapitre tait de vous montrer comment utiliser un plug-in pour vous faciliter
le traitement de donnes. Dans ce cas prcis, notre code est trs simple, nous aurions pu
nous passer de SimpleJSON mais dans un projet rel de nombreuses informations seront
changes entre votre application et votre serveur et cest l que le plug-in devient
indispensable. Avec SimpleJson, vous pourrez transformer une trs grande chane de
caractres en simple tableau facile lire. En effet, vous aurez un tableau personnage dans
lequel toutes les informations seront stockes. Si par exemple vous voulez rcuprer ou
modifier la vie du personnage vous pourrez y accder facilement comme cela :
personnage["vie"]. Il nest pas possible de travailler directement avec une chane de
caractres et nous devons utiliser la technique que je vous ai montre ici. Dans le jagon
informatique, cela sappelle parser une chane de caractres.
Note > Un autre avantage lorsque vous utilisez SimpleJSON, cest que vous pourrez
naviguer plus facilement dans les informations que vous allez recevoir. Par exemple, si
votre serveur vous renvoie des centaines de comptes joueurs, vous pourrez accder un
joueur en particulier en utilisant un code similaire celui-ci : joueur[10]["pseudo"]. Dans cet
exemple, je rcupre le pseudo du joueur n10. Vous pouvez aussi utiliser les boucles (for,
foreach, while) pour naviguer dans ce tableau. Toutes ces oprations sont impossibles avec
un simple texte non pars.

Dans ce chapitre, nous avons vu comment :

appeler les fonctions de notre API avec Unity ;


crer un systme dinscription/connexion ;
rcuprer et parser le JSON reu ;
utiliser le plug-in SimpleJSON.
12
Quelques fonctionnalits bien utiles
Les dveloppeurs ont pour habitude de dire Lorsque nous avons dvelopp 90 % du jeu,
il reste les autres 90 % dvelopper. Cette citation peut tre interprte de plusieurs
faons mais lessentiel comprendre est que lorsque la fin du dveloppement approche, il
reste autant de travail raliser que ce qui a dj t fait. En effet, aprs avoir dvelopp
votre jeu vous allez vous rendre compte que de nombreuses fonctionnalits sont
manquantes, que des bugs sont prsents et quil y a eu certains oublis.
Note > Dans ce chapitre, vous allez dcouvrir quelques astuces qui vont vous permettre de
finaliser votre jeu et de le peaufiner afin de devancer les concurrents. Vous verrez
comment lamliorer et comment intgrer des fonctionnalits indispensables.

1. La version alpha
Lorsque le dveloppement touche sa fin, vous pouvez lancer ce que lon appelle une
phase alpha qui consiste faire tester votre jeu quelques privilgis afin de dtecter
dventuelles anomalies. Il est prfrable de faire venir des joueurs dans vos locaux afin
de prendre un papier et un stylo et de noter tout ce quils font. Si les tests se font
distance, pensez demander aux testeurs de remplir un formulaire trs complet.
Pour avoir dj ralis de telles phases de tests, je peux vous assurer que certains joueurs
pensent linverse de ce que vous pensez et utilisent votre jeu dune faon que vous
nauriez mme pas imagin. Il mest arriv de voir des joueurs faire des choses
malencontreusement permises par le jeu qui les bloquent dfinitivement. Cest l que vous
vous rendez compte des diffrents points corriger. Vous devez toujours faire attention
ce que les joueurs peuvent faire et vrifier leurs actions. Pendant et aprs la phase alpha,
vous serez amen modifier votre code afin de rmdier aux anomalies rencontres.

2. La phase bta
Aprs la phase alpha arrive la phase bta. La diffrence entre les deux cest que la bta est
un test grande chelle. Le principe est de faire tester votre jeu par un grand nombre de
joueurs (entre 1000 et 10 000 en fonction du projet) afin de voir comment cela se passe en
grandeur nature. Pour un jeu en ligne cela vous permettra de tester si les serveurs tiennent
la charge ou encore sil est possible de tricher dans votre jeu.
La phase bta permet de dtecter de nouveaux bugs mais surtout elle vous permettra de
voir si votre jeu est stable et optimis. En gnral, cest durant cette phase que vous vous
rendez compte que des ralentissements peuvent se produire et que vous devez optimiser
votre jeu, rduire la qualit des textures, rduire la complexit des modles 3D, etc. De
nombreux studios dcident ce moment-l de rduire la qualit de leurs jeux en vue de les
optimiser pour tous les appareils, cest pourquoi entre la prsentation dun jeu dans un
salon de jeu vido et sa sortie vous constatez parfois une diffrence entre les graphismes
qui ont t prsents et les graphismes rels.
3. Partage sur les rseaux sociaux
Ajouter une fonctionnalit de partage sur les rseaux sociaux est un moyen facile dattirer
de nouveaux joueurs. Vous pouvez par exemple leur donner la possibilit de partager leur
score et dentrer ainsi en comptition avec leurs amis qui voudront jouer et faire mieux.
Vous gagnerez de nouveaux utilisateurs avec cette technique.
Nous allons utiliser la technique la plus simple mettre en place : proposer un lien. Nous
illustrerons cet exemple avec un partage Facebook. Commencez par placer un bouton ou
une image cliquable dans votre jeu. Vous pouvez soit mettre un bouton sur laccueil, soit
dans un menu pause si vous en avez un, soit afficher le bouton dans un coin de lcran.
Pour ma part, je prfre passer par le menu principal, voil mon bouton Facebook :
Figure 12.1 : Bouton de partage Facebook

Il sagit dune simple image avec le composant UI Button afin de pouvoir prendre en
charge le clic. Vous pouvez crer un nouveau script PartageFacebook et crer une
fonction Share(). Celle-ci contiendra juste le code Application.OpenURL(lien);. La
variable lien est une chane de caractres de cette forme :
String lien = "https://www.facebook.com/dialog/feed?app_id=" + appId +
"&display=popup&caption=" + caption + "&link=" + link + "&redirect_uri=" +
link + "&picture=" + pictureUrl + "&description=" + text +" " + score;

Cette URL permet dactiver la fentre de partage Facebook. Plusieurs variables sont
appeles dans cette URL. Vous devez spcifier le titre , le texte , limage , le lien de
llment que vous souhaitez partager . Vous devez galement spcifier lID de votre
application , nous allons y revenir dans un instant. Voil mes variables avec les
diffrentes valeurs :
public static int score = 0;
public string appId = "350979138382932";

public string caption = Jeu PC gratuit; public string link =


https://play.google.com/store/apps/developer?id=Formation+facile&hl=fr_FR;
public string pictureUrl = http://site.fr/image.jpg; public string text = Tentez de
batter mon score : ;
Ce code vous permettra de donner la possibilit aux joueurs de partager votre jeu sur
Facebook, cest aussi simple que cela.
Encadr : Obtenir un identifiant Facebook pour son jeu
Pour fonctionner, le script prcdent a besoin dun identifiant App ID attribu par
Facebook. Pour lobtenir, vous devez enregistrer votre jeu (Create New App) sur leur
plateforme. Voici la marche suivre :
Rendez-vous sur le tableau de bord des dveloppeurs Facebook et crez une nouvelle
application :
Figure 12.2 : Cration dune application Facebook

Choisissez un nom et une catgorie pour votre application :


Figure 12.3 : Cration dune application Facebook
Allez dans les options de votre application (Settings). Reprez lApp ID, cest ce
numro dont vous avez besoin dans votre script C#. Puis ajoutez une nouvelle
plateforme :
Figure 12.4 : Ajout dune plateforme pour lapp Facebook

Cliquez sur Website :


Figure 12.5 : Ajout de la plateforme Website
Enfin ajoutez lURL que vous voulez partager dans vos jeux.
Figure 12.6 : Association de lURL lapplication

Vous devez spcifier la mme URL trois fois (App domains, Site URL and Mobile Site
URL). Cliquez sur enregistrer. Copiez votre App ID.
Figure 12.7 : Obtention de lApp ID
Retournez dans Unity pour coller lApp ID et terminer votre script. Voici le rsultat
obtenu :

Figure 12.8 : Rsultat du partage

Astuce > Vous trouverez avec les sources du livre un plug-in (EasyFaceBook) que jai
dvelopp partir de ce code et qui vous permettra dintgrer trs facilement Facebook
vos jeux, sans toucher au code. Une petite documentation y est jointe au format PDF.
Note > Vous pouvez galement proposer au joueur le partage Twitter ou encore Google+.
Vous trouverez facilement les URL de partage pour chaque plateforme. Par exemple pour
Twitter lURL sera https://twitter.com/intent/tweet?text=Mon%20texte et dans le
cas de Google+ https://plus.google.com/share?url=votre-url-ici.
4. Rcuprer lavis des joueurs
Une autre fonctionnalit importante est la rcupration des avis. Vous devez donner la
possibilit aux joueurs de sexprimer (par e-mail, via un formulaire) afin quil puisse faire
ses retours qui vous seront utiles pour les mises jour de votre jeu. Vous pouvez donc
mettre en place un petit formulaire de notation trs simple comme par exemple :
Figure 12.9 : Formulaire : donner son avis

Bien que ce formulaire soit trs simple, il permettra au joueur de donner son avis. Vous
pouvez demander les informations de votre choix mais une note et un commentaire
permettent dj davoir une ide prcise de ce que le joueur pense.
Vous pouvez rcuprer le contenu de ce formulaire de plusieurs faons :

par la classe WWW :


using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Avis : MonoBehaviour {

private string url = "http://www.site.fr/Avis.php";


private WWW download;
public Text note;
public Text avis;

public void CallFunction()


{
StartCoroutine(DonnerAvis());
}
public IEnumerator DonnerAvis ()
{
url = url+"?note="+note.text+"&avis="+ avis.text;
download = new WWW(url);
yield return download;

if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
print ("Ok");
}
}
}

en PHP :
<?php require_once "Helper.php";
$helper = new Helper();

if(isset($_GET["note"]) && isset($_GET["avis"])){

$note = $_GET["note "];


$avis = $_GET["avis "];

$helper->DonnerAvis($note, $avis);
// Vous pouvez envoyer un mail galement
} else {
echo "Erreur, veuillez saisir tous les champs.";
}
?>

Cela implique que vous criez une table avis dans la base de donnes ainsi quune
fonction DonnerAvis dans votre classe Helper.php. La seconde solution consiste vous
envoyer lavis par e-mail directement partir de Unity. Pour retrouver le code complet
permettant denvoyer un e-mail avec Unity, je vous invite lire la foire aux questions en
fin douvrage.
5. Systme de bannire
Si vous souhaitez nouer des partenariats ou afficher des publicits, vous gagnerez mettre
en place un systme de bannires. Cela vous permettra par exemple de montiser votre jeu
ou de gagner de nouveaux utilisateurs.
Limage de notre bannire sera stocke sur notre serveur et affiche dynamiquement. Nous
pourrons ainsi librement la modifier sans toucher au code de lapplication. Pour cela, nous
utiliserons la classe WWW. Pour raliser ce script, nous allons crer un plane (un simple
objet 3D rectangulaire plat) ou un quad (similaire au plane mais visible que dun ct) en
passant par le menu GameObject. Positionnez votre plane afin de le faire apparatre
lcran :
Figure 12.10 : Bannire vide

Nous pouvons commencer par crer une variable de type string qui contiendra lURL vers
limage se trouvant sur votre serveur :
string url = "https://placeholdit.imgix.net/~text?
txtsize=50&txt=Contenu%20de%20ma%20banniere&w=600&h=150";

Jutilise le site http://placehold.it qui gnre une image automatiquement pour faire nos
essais. La classe WWW permet de charger une texture via la fonction
LoadImageIntoTexture. Voil le code crire :

using UnityEngine;
using System.Collections;

public class LoadImageURL : MonoBehaviour {

string url = "https://placeholdit.imgix.net/~text?


txtsize=50&txt=Contenu%20de%20ma%20banniere&w=600&h=150";

IEnumerator Start () {
GetComponent<Renderer>().material.mainTexture = new Texture2D(4, 4,
TextureFormat.DXT1, false);
while(true) {
WWW www = new WWW(url);
yield return www;
www.LoadImageIntoTexture(GetComponent<Renderer>
().material.mainTexture as Texture2D);
}
}

Dans cette fonction Start, nous crons une nouvelle texture vide pour notre bannire et
nous tlchargeons limage spcifie dans lURL grce WWW, puis nous lutilisons
comme texture pour notre bannire afin de lafficher lcran. Le while nous permet de
donner le temps au script de tlcharger limage en ligne (cela peut prendre plus ou moins
de temps en fonction de la taille de limage que vous tlchargez).
Placez le script sur votre plane et regardez le rsultat :
Figure 12.11 : Bannire dynamique

Le script va bien rcuprer la texture en ligne et lappliquer au plane. La dernire chose


grer est le clic, exemple :
void OnMouseUp()
{
Application.OpenURL("http://site.fr/partenaire.php");
Destroy(this.gameObject) ;
}

Vous pouvez maintenant afficher de la publicit, une annonce, prsenter un jeu ou un site
via cette bannire. Vous pouvez aussi la faire disparatre au bout de 30 secondes si le
joueur ne clique pas dessus afin de ne pas le perturber.
Nhsitez pas ajouter dautres fonctionnalits si vous avez des ides positives pour votre
jeu.

Dans ce chapitre, vous avez vu comment :

faire tester votre jeu ;


inclure le partage Facebook votre jeu ;
demander aux joueurs leur avis ;
crer une bannire dynamique.
Et aprs ?
Vous savez maintenant comment utiliser le nouveau systme UNET de Unity. Conu pour
simplifier la mise en rseau, il vous permettra non seulement de crer rapidement des jeux
multijoueurs mais aussi de mettre en place un mode en ligne pour un jeu monojoueur
existant. Au-del de cette couche rseau, nous avons galement vu comment se connecter
un serveur web ainsi qu une base de donnes. Cette tape importante est indispensable
pour conserver sur votre serveur des informations relatives aux joueurs en ligne. Cest par
ce biais que vous pourrez galement recueillir des statistiques, mettre en place un systme
de qutes journalires ou encore un outil permettant au joueur de tlcharger des lments
supplmentaires comme par exemple un niveau ou des objets bonus.
Ce livre est une premire approche dans la programmation de jeux en ligne. Ces bases
seront suffisantes pour tous vos projets si vous creusez un peu et crez des fonctionnalits
plus pousses. Pour les jeux de grande envergure (MMORPG succs), il faudra opter
pour un abonnement au service de networking propos par Unity.
Foire aux questions
1. Comment synchroniser les animations sur le
rseau ?
UNET propose un composant appel Network Animator qui permet de synchroniser les
animations de lobjet possdant ce composant sur le rseau. Vous avez simplement besoin
dun Animator pour que les animations puisse tre synchronises.

2. quoi sert le Network Lobby Manager ?


Il sagit dun composant complexe permettant de grer de nombreux paramtres. Vous
pouvez lutiliser pour limiter le nombre de joueurs, lancer automatiquement la partie
quand tous les joueurs sont prts, bloquer les connexions si le jeu a dmarr, grer les
clients qui contrlent plusieurs joueurs, etc.

3. Quest ce que le Network Lobby Player ?


Cest un composant utilis par le Network Lobby Manager qui permet dafficher des
informations lcran, de rcuprer lemplacement du joueur dans le lobby et de dire si le
joueur est prt jouer ou pas.
4. Que peut-on faire avec le Network Proximity
Checker ?
Ce composant permet de contrler la visibilit des objets sur le rseau en fonction de la
distance qui spare les joueurs. Vous pouvez donc rendre invisible certains objets en
dehors dun certain rayon.

5. Comment choisir la position dinstanciation du


joueur ?
Par dfaut, le Network Manager instancie le joueur au centre de la scne. Il est cependant
possible de dfinir manuellement la position dinstanciation de plusieurs faons. Le
Network Start Position est utilis par le manager pour crer le personnage une position
dfinie.

6. Quest ce que le Network Transform


Visualizer ?
Ce composant vous permet de visualiser linterpolation des personnages ayant un Network
Transform sur le rseau.
7. Comment crer un jeu capable de grer des
milliers de connexions ?
Si vous souhaitez crer un MMO (jeu en ligne massivement multijoueur), il faudra passer
par un serveur capable de grer des centaines de connexions. Unity propose un service,
payant partir dune certaine utilisation, qui permet de grer les joueurs de votre jeu et de
crer des parties sur les serveurs de Unity. Retrouvez ce service ladresse
https://multiplayer.unity3d.com.

8. Comment gnrer un niveau partir dun


fichier stock en ligne ?
Vous pouvez gnrer un niveau partir dun fichier texte stock sur votre serveur grce
la classe WWW. Vous tlchargez le texte contenu dans le fichier et vous lutilisez pour
gnrer le niveau avec la fonction Instanciate. Par exemple, si votre fichier texte
contient 1 0 0 0 1 2 0 2 1, vous pouvez gnrer des objets en fonction des chiffres
contenus dans le fichier. La fonction C# Split(' ') peut vous permettre de dcouper la
chane de caractres pour stocker chaque nombre dans un tableau.

9. Comment tlcharger une texture en ligne et


lappliquer un objet ?
Toujours avec la classe WWW, vous pouvez tlcharger une texture en ligne pour
lappliquer un objet comme cela :
public string url = "http://site.fr/image.jpg";
IEnumerator Start() {
WWW www = new WWW(url);
yield return www;
Renderer renderer = GetComponent<Renderer>();
renderer.material.mainTexture = www.texture;
}
10. Peut-on envoyer un e-mail partir dun jeu ?
Oui, il est possible denvoyer un e-mail mme si cela reste complexe. Vous pouvez passer
par WWW pour appeler un script PHP qui enverra un message votre place ou vous
pouvez crer un script C# comme celui-ci :
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public class SendMail : MonoBehaviour {

void Main ()
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("votremail@gmail.com");
mail.To.Add("destinataire@gmail.com");
mail.Subject = "Test Mail";
mail.Body = "Message de test";
SmtpClient smtpServer = new SmtpClient("smtp.gmail.com");
smtpServer.Port = 587;
smtpServer.Credentials = new System.Net.NetworkCredential(
"votremail@gmail.com",
"votrepassword") as ICredentialsByHost;
smtpServer.EnableSsl = true;
ServicePointManager.ServerCertificateValidationCallback =
delegate(object s,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{ return true; };
smtpServer.Send(mail);
}
}

Dans cet exemple nous utilisons Gmail pour envoyer le-mail au destinataire.

11. Quels autres langages pouvons-nous utiliser


sur notre serveur ?
Dans ce livre, nous avons utilis le PHP, un langage populaire et gratuit pour raliser nos
exemples. Vous pouvez bien sr utiliser dautres langages comme du Prolog, du Perl
Beaucoup de langages peuvent tre utiliss. Il existe des langages asynchrones trs
puissant permettant de grer un grand nombre de connexions comme par exemple Scala.
Vous pouvez galement renvoyer des donnes sous forme de texte, de JSON comme nous
lavons vu, ou encore au format XML si vous prfrez.
Lexique
A
Application Programming Interface
Interface de programmation
Une API est un service proposant un ensemble de fonctions permettant daccder
des donnes.

B
Base de donnes
Une base de donnes est un conteneur informatique permettant le stockage de
nombreuses donnes. Le langage SQL est un langage permettant dinterroger les
bases de donnes afin daccder ces donnes.

C
Client
Cest un joueur qui sest connect au serveur hbergeant la partie.

F
FireWall
Pare-feu
Un pare-feu est un logiciel permettant de dfinir une politique de scurit. Pour jouer
certains jeux en ligne, il faut ajouter une autorisation au pare-feu.

H
Host
Hte
Lorsquun client joue galement le rle du serveur, on lappelle un hte.
L
Lag
Latence, dlai de transit, retard

P
Plug-in
Extension
Petit programme permettant dajouter des fonctionnalits un logiciel.

S
Serveur
Il sagit dun ordinateur sur lequel une partie est hberge. Les joueurs peuvent se
connecter au serveur via une IP.

T
Tag
tiquette, mot cl
Marqueur permettant dassocier des objets une catgorie et des caractristiques
afin de les regrouper et de les identifier.
TCP
Protocole de Contrle de Transmission
Cest un protocole de transmission de donnes qui permet de vrifier que les donnes
ont bien t reues et dans lordre.

U
UDP
Protocole de Datagramme Utilisateur
Cest un protocole de transmission de donnes qui ne fournit pas de contrle
derreurs.
Index
A
Alpha, Quelques fonctionnalits bien utiles
API, Cration dune API PHP, Utilisation de lAPI avec SimpleJSON
Authority, Le principe dautorit (Authority)

B
Base de donnes, Utilisation dune base de donnes, Prparation de la base de donnes
Bta, La phase bta
Build settings, Configuration du Network Manager, Script de slection du niveau

C
Client, La notion de client/serveur
Compiler, Configuration du Network Manager
Coroutine, Prparation des variables stocker en ligne
CRUD, Cration dune API PHP

E
vnement
On Value Changed, Configuration du nombre de joueurs
souris, Association des fonctions au menu, Script de slection du niveau, Systme de
bannire

F
Facebook, Partage sur les rseaux sociaux

H
Hbergeur, Les outils que nous allons utiliser
Host, Le systme de host, Cration du script Menu

I
IEnumerator, Prparation des variables stocker en ligne, Cration dun compte joueur
Instanciation, Instanciation sur le rseau
Interpolation, Linterpolation, Cration dune fonction de synchronisation de la position
crer une, Cration dune fonction de synchronisation de la position

IP, La notion de client/serveurisClient, Quelques proprits bien utilesisLocalPlayer,


Quelques proprits bien utilesisServer, Quelques proprits bien utiles

J
JSON, Cration dune API PHP, Utilisation de lAPI avec SimpleJSON

L
Lerp, Cration dune fonction de synchronisation de la position

M
Menu, Mise en rseau

N
netId, Quelques proprits bien utiles, Tirer sur les autres joueurs
Network Animator, Comment synchroniser les animations sur le rseau ?
Network Identity, Le Network Identity
malvenu, Script de slection du niveau

Network Lobby Manager, quoi sert le Network Lobby Manager ?Network Lobby
Player, Quest ce que le Network Lobby Player ?Network Manager, Le Network
ManagerNetwork Manager HUD, Le Network ManagerNetwork Proximity Checker, Que
peut-on faire avec le Network Proximity Checker ?Network Start Position, Comment
choisir la position dinstanciation du joueur ?Network Transform, Le Network Transform
O
Optimisation, Optimisation pour le rseau

P
Paquet, La notion de client/serveur
Partage rseaux sociaux, Partage sur les rseaux sociaux
Pause, Prparation des variables stocker en ligne
PHPmyAdmin, Les outils que nous allons utiliser
Playerprefs, Prparation des variables stocker en ligne
Plug-in
installer, Utilisation de lAPI avec SimpleJSON

Port, Le Network ManagerProtocole de communication, Les protocoles de communication

R
Rseaux sociaux, Partage sur les rseaux sociaux

S
Serveur, La notion de client/serveur, Utilisation dune base de donnes
stockage, Prparation des variables stocker en ligne, Systme de bannire

SimpleJSON, Utilisation de lAPI avec SimpleJSONSpawn, Quelques proprits bien


utiles, Prparation du Network ManagerStartCoroutine, Prparation des variables stocker
en ligne, Cration dun compte joueurSynchronisation

animation, Comment synchroniser les animations sur le rseau ?


de la position, Le Network Transform, Cration dune fonction de synchronisation de la
position

T
TCP, Les protocoles de communication
Transform, Le Network Transform
U
UDP, Les protocoles de communication
UNET, Dcouverte dUNET

W
Wamp, Les outils que nous allons utiliser
WWW, classe, Rcuprer lavis des joueurs, Systme de bannire
WWWForm, Envoyer des variables un script PHP

Y
yield, Cration dun compte joueur
Crez des jeux de A Z avec Unity - IV. Rseau et mode multijoueur
Aperu gnral de louvrage
Copyright
propos de lauteur
Introduction
Ce dont vous avez besoin et prrequis
Quallez-vous apprendre dans ce livre ?
Comment bien apprendre avec ce livre?
Rglage de la largeur de lcran
URL raccourcies
Notions fondamentales du rseau
La notion de client/serveur
Les protocoles de communication
Le systme de host
Linterpolation
Le principe dautorit (Authority)
Dcouverte dUNET
Le Network Manager
Le Network Identity
Le Network Transform
Quelques proprits bien utiles
Mise en rseau
Cration du menu principal
Configuration du Network Manager
Contrle du personnage local
Instanciation sur le rseau
Prparation du Network Manager
Utilisation de la fonction Spawn
Interactions entre joueurs
Synchronisation des variables
Tirer sur les autres joueurs
Optimisation pour le rseau
Cration dune fonction de synchronisation de la position
Synchronisation de la position du viseur
Destruction des objets instancis
Cration dun menu personnalis
Cration du menu
Cration du script Menu
Association des fonctions au menu
Afficher le score
Menu Options et modes de jeux
Cration dun menu de slection des niveaux
Script de slection du niveau
Configuration du nombre de joueurs
Utilisation dune base de donnes
Les outils que nous allons utiliser
Prparation des variables stocker en ligne
Envoyer des variables un script PHP
Cration du script PHP de sauvegarde dans la base
Cration dune API PHP
Prparation de la base de donnes
Cration de la classe Helper.php et des fonctions
Cration de la fonction de connexion
Pour aller plus loin
Utilisation de lAPI avec SimpleJSON
Cration dun compte joueur
Cration de la scne de connexion
Quelques fonctionnalits bien utiles
La version alpha
La phase bta
Partage sur les rseaux sociaux
Rcuprer lavis des joueurs
Systme de bannire
Et aprs ?
Foire aux questions
Comment synchroniser les animations sur le rseau ?
quoi sert le Network Lobby Manager ?
Quest ce que le Network Lobby Player ?
Que peut-on faire avec le Network Proximity Checker ?
Comment choisir la position dinstanciation du joueur ?
Quest ce que le Network Transform Visualizer ?
Comment crer un jeu capable de grer des milliers de connexions ?
Comment gnrer un niveau partir dun fichier stock en ligne ?
Comment tlcharger une texture en ligne et lappliquer un objet ?
Peut-on envoyer un e-mail partir dun jeu ?
Quels autres langages pouvons-nous utiliser sur notre serveur ?
Glossaire
Index

Вам также может понравиться