Академический Документы
Профессиональный Документы
Культура Документы
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 !
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
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
Cette fonction, trs utile, permet de savoir si lobjet est un objet du joueur local.
netId
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]
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
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
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;
{ 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;
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.
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.
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
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]
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.
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;
[SyncVar]
public uint idPlayer;
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;
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
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;
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.
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.
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 :
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;
Le hostNameInput est un champ de texte dans lequel nous pouvons spcifier le nom de
lhte (ou son IP).
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.
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 :
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
Ouvrez le script Joueur pour y ajouter les fonctionnalits ncessaires. Commencez par
inclure la bibliothque UI dans son en-tte :
using UnityEngine.UI;
Cest tout pour le moment ! Dans le prochain chapitre nous allons enrichir ce menu dun
slecteur de niveaux.
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;
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;
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;
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.
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));
[SyncVar]
public uint idPlayer;
public int degats = 1;
if(PlayerPrefs.HasKey("bestscore"))
{
PlayerPrefs.SetInt("bestscore",
PlayerPrefs.GetInt("bestscore") + 1);
}
else{
PlayerPrefs.SetInt("bestscore", 1);
}
StartCoroutine(SaveScoreOnline("Joueur"+idPlayer));
}
}
}
}
}
}
}
}
}
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"));
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");
}
}
// 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."');";
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";
}
$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 :
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();
$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
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"
}
]
}
{
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.
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
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()
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.
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;
Nous rcuprons le JSON renvoy par le serveur et nous le stockons dans la variable
monJson.
Nous affichons le pseudo de lutilisateur dans la console afin de vrifier que tout
fonctionne.
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.
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";
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 :
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 :
if ((!string.IsNullOrEmpty(download.error)))
{
print("Error downloading: " + download.error);
}
else
{
print ("Ok");
}
}
}
en PHP :
<?php require_once "Helper.php";
$helper = new Helper();
$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;
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
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.
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.
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
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
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
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