UNITY 3 D BEKRI Kacem 11 octobre 2012
UNITY 3 D BEKRI Kacem 11 octobre 2012 24 et 25 octobre 2012 21 et 22 novembre 2012 ISTIA - Master IVI/MNRV
Résumé • Résolument orientée sur la pratique, cette formation permet d'acquérir les compétences nécessaires pour développer des applications multimédias avec Unity 3 D. • Après une présentation des fondamentaux d'Unity 3 D, vous découvrirez ses outils et son interface utilisateur qui en font une plateforme unique. • Le programme est découpé par thème. Chacun des thèmes est abordé par la théorie puis un travail pratique permet de mettre en œuvre les éléments abordés.
Chapitre 1 Principe • Présentation • Environnement de développement Le temps réel L’éditeur et l’interface • Les langages • L’interface
Chapitre 2 Collisions • Collider • Trigger • Rigidbody Le terrain • Génération Inputs • Clavier • Souris • Joystick Particules • Exemples
Chapitre 3 Editeur 3 D Les matériaux • Maya • 3 DS Max • Lights • Shaders Animations La GUI • Textes • Boutons • Images
Chapitre 4 Smart. Fox. Server Le player Web • Initialisation • Chat system • Le cache Réseau • Exemple • Classe www
Chapitre 5 Projet personnel
Chapitre 1
Principes 1 • WYSIWYG What You See Is What You Get 2 • Licence gratuite (limitée) 3 • Cross-plateform
Licence
Multi plateformes i. OS Android Windows Phone 8 Blackberry 10 Windows Store App Mac Linux Web Player PS 3 Xbox 360 Wii U
L’éditeur et son interface • Langage – C# – javascript
L’EDITEUR Scene : Mes objets en 3 D Game : Ce qu’on obtient Hierarchy: Liste de mes objets Project: Mon disque dur Inspector: Détail de l’objet sélectionné
CRÉATION D’UN CUBE Créez un cube via le menu Game. Object Il apparait dans la fenêtre Hierachy (Liste de mes objets)
CRÉATION D’UN SCRIPT C# Créez un C Sharp Script dans la fenêtre Projet Renommez le fichier cs en Rotate. Me. cs Modifiez le nom de la classe en Rotate. Me public class Rotate. Me : Mono. Behaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
CRÉATION D’UN SCRIPT C# Glissez le script Rotate. Me sur l’objet Cube que vous venez de créer.
CLASSE MONOBEHAVIOR A chaque fois que la public class Rotate. Me : Mono. Behaviour { méthode Update() est Question : private float x_deg; appelée : On tourne autour de Comment s’assurer que le cube tourne toujours // Use this for initialization à la même vitesse quelles que soient les l’axe UP de x_deg void Start () { performances de la machine que j’utilise ? degrés x_deg = 10. 0 f; } // Update is called once per frame void Update () { transform. Rotate(Vector 3. up, x_deg); } }
GAME LOOP La méthode Update() de chaque objet est appelée en boucle Begin End On affiche les textes et boutons 2 D On. GUI Update Draw On bouge les objets On affiche les objets
GAME LOOP A chaque appel, l’objet tourne de x_deg degrés Begin End Update transform. Rotate(Vector 3. up, x_deg); On. GUI Draw
TIME. DELTATIME Machine performante Pour que le cube tourne à la même vitesse sur • Affiche 200 images/seconde ces trois machines, il faut que la rotation dans • On exécute la fonction Update() 200 fois par sec chaque Update() soit moins importante sur les machines puissantes. Machine moyenne • Affiche 60 images/seconde • On exécute la fonction Update() 60 fois par sec Machine ancienne • Affiche 10 images/seconde • On exécute la fonction Update() 10 fois par sec
TIME. DELTATIME Machine performante • Affiche 200 images/seconde • Valeur fournie par Unity : Time. delta. Time = 1/200 s Machine moyenne • Affiche 60 images/seconde • Valeur fournie par Unity : Time. delta. Time = 1/60 s Machine ancienne • Affiche 10 images/seconde • Valeur fournie par Unity : Time. delta. Time = 1/10 s
TIME. DELTATIME public class Rotate. Me : Mono. Behaviour { private float x_deg; La vitesse est constante // Use this for initialization car le Time. delta. Time void Start () lisse les performances. { x_deg = 100. 0 f; } // Update is called once per frame void Update () { transform. Rotate(Vector 3. up, Time. delta. Time * x_deg); } }
Les paramètres public s’affichent automatiquement dans l’Inspector. LES PARAMÈTRES public class Rotate. Me : Mono. Behaviour { public float x_deg = 100. 0 f; // Use this for initialization void Start () { } } // Update is called once per frame void Update () { transform. Rotate(Vector 3. up, Time. delta. Time * x_deg); }
Exercice 1 : Un cube qui tourne
Exercice 2 : Plusieurs objets Contrainte : utilisez un seul script
MULTIPLES OBJECTS public class Rotate. Me : Mono. Behaviour { public float x_deg = 10. 0 f; public int axe = 0; } // Update is called once per frame void Update() { if (axe == 0) { transform. Rotate(Vector 3. up, Time. delta. Time * x_deg); } else if (axe == 1) { transform. Rotate(Vector 3. right, Time. delta. Time * x_deg); } else if (axe == 2) { transform. Rotate(Vector 3. forward, Time. delta. Time * x_deg); } }
MULTIPLES OBJECTS public class Rotate. Me : Mono. Behaviour { public float x_deg = 10. 0 f; public Vector 3 axe = Vector 3. up; // Update is called once per frame void Update() { transform. Rotate(axe, Time. delta. Time * x_deg); transform. position = new Vector 3(10. 0 f, 52. 0 f); } } float position_x = transform. position. x;
Travaux pratiques 1
Travaux pratiques 1 Tutorial : 3 D Platform Lerpz
Chapitre 2
Le terrain Créer un terrain simplement
Système de particules
Le terrain • Créer une ile – Avec un lagon et une plage – Avec un volcan • Ajouter des FX – Lave rouge qui sort du volcan – Brouillard léger sur l’eau • Utiliser une skybox
Les inputs • • • Clavier Souris Joystick Wiimote …
Comment lire le clavier ? Utilisons l’aide de Unity 3 D : Recherche « Get. Key »
Comment lire le clavier ? public class Rotate. Me. On. Click : Mono. Behaviour { public float vitesse; // Use this for initialization void Start () { vitesse = 10. 0 f; } // Update is called once per frame void Update () { if (Input. Get. Key(Key. Code. Up. Arrow)) { transform. Rotate(Vector 3. up, vitesse); } } }
Afficher les coord au clic de la souris public class Detect. Mouse : Mono. Behaviour { // Update is called once per frame void Update () { if (…) { Debug. Log(… } } }
La physique • Collider – Interaction avec la physique • Rigidbody – Objet indépendant • Trigger – Action sur collision
La physique : exemple simple
Travaux pratiques 2
Travaux pratiques 2 Tutorial : Destruction Time
Détecter le clic de souris public class Game : Mono. Behaviour { public Game. Object boulet; // Use this for initialization void Start() { } // Update is called once per frame void Update() { if (Input. Get. Mouse. Button. Down(0)) { // On appuie sur le bouton de la souris } } } Debug. Log("mouse. Position = " + Input. mouse. Position);
Instancier un boulet de canon public class Game : Mono. Behaviour { public Game. Object boulet; // Use this for initialization void Start() { } } // Update is called once per frame void Update() { if (Input. Get. Mouse. Button. Down(0)) { // Create a bullet if hit Game. Object fire = (Game. Object) Instantiate(boulet, transform. position, transform. rotation); } }
Lancer le boulet de canon // Update is called once per frame void Update() { if (Input. Get. Mouse. Button. Down(0)) { // Construct a ray from the current mouse coordinates Ray ray = Camera. main. Screen. Point. To. Ray(Input. mouse. Position); // Create a bullet if hit Game. Object fire = (Game. Object) Instantiate(boulet, transform. position, transform. rotation); // launch the bullet fire. rigidbody. Add. Force(ray. direction * 1000. 0 f); } }
Chapitre 3 • Les éditeurs 3 D • La GUI • Une machine à Etat
Les éditeurs 3 D compatibles
Comment ajouter des Assets 3 D ? Sous l’explorateur Windows : Copier le fichier 3 D dans le répertoire « Assets » de votre projet. N’oubliez pas de copier aussi les textures (dans un répertoire « Textures » par exemple)
TD : Importez votre scène 3 D – Créez une nouvelle scène Unity – Ajoutez votre scène 3 D personnelle – Réglez les matériaux/lights – Créez un C# script « Quake. Camera » – Assignez-le à la camera – Modifiez le script pour permettre de vous déplacer dans votre scène avec les touches : Up. Arrow, Down. Arrow, Left. Arrow, Right. Arrow, Page. Up, Page. Down
TD : Importez votre scène 3 D public class Quake. Camera : Mono. Behaviour { public float vitesse. Translation = 10. 0 f; public float vitesse. Rotation = 100. 0 f; // Update is called once per frame void Update() { if (Input. Get. Key(Key. Code. Up. Arrow)) { transform. Translate(…); } …Down. Arrow… …Right. Arrow… …Left. Arrow… …Page. Up… …Page. Down… } }
TD : Importez votre scène 3 D // Update is called once per frame void Update() { if (Input. Get. Key(Key. Code. Up. Arrow)) // Avancer { transform. Translate(Vector 3. forward * vitesse. Translation * Time. delta. Time); } if (Input. Get. Key(Key. Code. Down. Arrow)) // Reculer { transform. Translate(Vector 3. forward * -vitesse. Translation * Time. delta. Time); } if (Input. Get. Key(Key. Code. Right. Arrow)) // Tourner à droite { transform. Rotate(Vector 3. up, vitesse. Rotation * Time. delta. Time); } if (Input. Get. Key(Key. Code. Left. Arrow)) // Tourner à gauche { transform. Rotate(Vector 3. up, -vitesse. Rotation * Time. delta. Time); } if (Input. Get. Key(Key. Code. Page. Up)) // Regarder en haut { transform. Rotate(Vector 3. left, vitesse. Rotation * Time. delta. Time); } if (Input. Get. Key(Key. Code. Page. Down)) // Regarder en bas { transform. Rotate(Vector 3. left, -vitesse. Rotation * Time. delta. Time); } }
La GUI Afficher une image simple
La GUI Afficher une image simple public Texture 2 D text. Victoire; void On. GUI() { GUI. Draw. Texture(new Rect(10, 200, 400), text. Victoire); } Comment la faire clignoter ?
La GUI Afficher une image simple qui clignote public Texture 2 D text. Victoire; void On. GUI() { if (Time. time % 1. 0 f > 0. 5 f) { GUI. Draw. Texture(new Rect(10, 200, 400), text. Victoire); } } Comment la faire grossir ?
La GUI Afficher une image simple qui grossi public Texture 2 D text. Victoire; void On. GUI() { float factor = 1. 0 f + Time. time % 1. 0 f; GUI. Draw. Texture(new Rect(10, 200 * factor, 400 * factor), text. Victoire); }
La GUI Afficher des boutons
La GUI Afficher 2 boutons public Texture 2 D text. Moins; public Texture 2 D text. Plus; void On. GUI() { if (GUI. Button(new Rect(0, 300, 100), text. Plus)) { } if (GUI. Button(new Rect(150, 300, 100), text. Moins)) { } } Comment centrer horizontalement les boutons ? Indice : La taille en x de l’écran est Screen. width
La GUI Centrer 2 boutons void On. GUI() { int center = Screen. width / 2; if (GUI. Button(new Rect(center - 50 - 100, 300, 100), text. Plus)) { } if (GUI. Button(new Rect(center + 50, 300, 100), text. Moins)) { } }
La GUI Comment alterner les 2 boutons ?
La GUI Alterner les 2 boutons bool show. Right = false; void On. GUI() { if (show. Right) { if (GUI. Button(new Rect(100, 300, 100), text. Plus)) { show. Right = false; } } else { if (GUI. Button(new Rect(250, 300, 100), text. Moins)) { show. Right = true; } } }
Travaux pratiques 3
Calcul mental Machine à états menu quit init calcul loose win score
Paramètres public class My. Game : Mono. Behaviour { string state = "menu"; public int nb. Calcul. Max = 10; int nb. Calcul. Done = 0; int nb. Calcul. Win = 0; int value 1; int value 2; int result 1; int result 2; int result 3; float timer. Delay = 3. 0 f; float timer; // Use this for initialization void Start() { } // Etat courant // Nombre de calculs par jeu // Nombre de calculs déjà fait // Nombre de calculs gagnés // les deux chiffres de départ // Les 3 résultats à afficher // Combien de temps on attends // Alarme a fixer à chaque calcul
Update() & On. GUI() public class My. Game : Mono. Behaviour { public string state = "menu"; (…) void Update() { switch(state) { case "init": Update. Init(); break; //case "calcul": Update. Calcul(); break; //case "win": Update. Win(); break; //case "loose": Update. Loose(); break; } } void On. GUI() { switch(state) { //case "calcul": On. GUICalcul(); case "menu": On. GUIMenu(); //case "score": On. GUIScore(); } } break; Tous les « GUI. » sont dans la méthode On. GUI()
On. GUIMenu() void On. GUIMenu() { // Si on appuie sur le bouton « Start » on passe à l’état « init » if (GUI. Button(new Rect(100, 100), "Start")) { nb. Calcul. Done = 0; (…) nb. Calcul. Win = 0; } state = "init"; } // Si on appuie sur le bouton « quit » on passe à l’étape « quit » (…) // Si on appuie sur le bouton « quit » on passe à l’étape « quit » } if (GUI. Button(new Rect(250, 100, 100), "Quit")) { state = "quit"; } } Le pas oublier d’initialiser les variables : nb. Calcul. Done nb. Calcul. Win
Update. Init() void Update. Init() {{ // On genère 2 nombre aléatoires pour l'entrée // On genère 1 nombre aléatoire entre 2 et 9 value 1 = Random. Range(2, 10); value 2 = Random. Range(2, 10); (…) } // On trouve les 3 résultats et on les affecte au hasard switch (Random. Range(0, 3)) { case 0: { result 1 = value 1 * value 2; result 2 = Random. Range(10, 100); result 3 = Random. Range(10, 100); break; } case 1: { result 1 = Random. Range(10, 100); result 2 = value 1 * value 2; result 3 = Random. Range(10, 100); break; } case 2: { result 1 = Random. Range(10, 100); result 2 = Random. Range(10, 100); result 3 = value 1 * value 2; break; } } Lors de l’étape « init » : • On génère 2 nombres aléatoires pour value 1 et value 2 • On calcule produit = value 1 x value 2 • On place au hasard ce produit avec deux autres nombres aléatoires dans les variables : result 1, result 2 et result 3 • On lance l’étape suivante : state = "calcul"; // On active l’alarme
Update. Init() int[] result = new int[3]; void Update. Init() { // On genère 2 nombre aléatoires pour l'entrée value 1 = Random. Range(2, 10); value 2 = Random. Range(2, 10); // On trouve les 3 résultats et on les affecte au hasard result[0] = Random. Range(10, 100); result[1] = Random. Range(10, 100); result[2] = Random. Range(10, 100); result[Random. Range(0, 3)] = value 1 * value 2; ; // On active l’alarme timer = Time. time + timer. Delay; state = "calcul"; }
Update. Init() ++ void Update. Init() { // On génère 2 nombre aléatoires pour l'entrée value 1 = Random. Range(2, 10); value 2 = Random. Range(2, 10); // On génère 2 nombre aléatoires pour la sortie int x = Random. Range(0, 3); result[x] = value 1 * value 2; result[++x%3] = Random. Range(10, 100); // On active l’alarme timer = Time. time + timer. Delay; state = "calcul"; }
On. GUICalcul() On affiche la formule et les 3 boutons réponses : void On. GUICalcul() { GUI. Label(new Rect(100, 300, 50), "" + value 1 + " x " + value 2 + " ? "); if (GUI. Button(new Rect(100, 200, 100), result 1. To. String())) { } if (GUI. Button(new Rect(220, 200, 100), result 2. To. String())) { } if (GUI. Button(new Rect(340, 200, 100), result 3. To. String())) { } } Si la réponse est bonne : « win » sinon : « loose »
void On. GUICalcul() { GUI. Label(new Rect(100, 300, 50), "" + value 1 + " x " + value 2 + " ? "); GUI. Label(new Rect(100, 150, 300, 50), "" + (int)(timer - Time. time + 1) + " s"); if (GUI. Button(new Rect(100, 200, 100), result 1. To. String())) { if (result 1 == value 1 * value 2) { state = "win"; } else { state = "loose"; } } if (GUI. Button(new Rect(220, 200, 100), result 2. To. String())) { if (result 2 == value 1 * value 2) { state = "win"; } else { state = "loose"; } } if (GUI. Button(new Rect(340, 200, 100), result 3. To. String())) { (…) } }
Update. Calcul() On. GUIScore() void Update. Calcul() { if (timer < Time. time) { // Out of time state = "loose"; } } void On. GUIScore() { GUI. Label(new Rect(100, 300, 50), “Score: " + nb. Calcul. Win + “/" + nb. Calcul. Done); if (GUI. Button(new Rect(100, 400, 200, 100), "Retour au menu")) { state = "menu"; } }
Update. Win() void Update. Win() { nb. Calcul. Win++; nb. Calcul. Done++; if (nb. Calcul. Done < nb. Calcul. Max) { state = "init"; } else { state = "score"; } } void Update. Loose() { nb. Calcul. Done++; if (nb. Calcul. Done < nb. Calcul. Max) { state = "init"; } else { state = "score"; } }
Chapitre 4 Le réseau
TÉLÉCHARGEMENTS Affectez ce script à un cube de votre scène public class download : Mono. Behaviour { void Start() { Start. Coroutine(Download("http: //www. cours. kacem. fr/cours/mario. jpg")); } IEnumerator Download(string url) { // Start a download of the given URL WWW www = new WWW(url); // Wait for download to complete yield return www; // assign texture renderer. material. main. Texture = www. texture; } }
Téléchargement Exercice : Affichez le contenu du texte situé à l’adresse : http: //www. cours. kacem. fr/cours/simple. txt public class download : Mono. Behaviour { string texte = "waiting. . . "; void Start() { Start. Coroutine(Download. Texte("http: //www. cours. kacem. fr/cours/simple. txt")); } } IEnumerator Download. Texte(string url) { IEnumerator Download. Texte(string url) … { // Start a download of the given URL } WWW www = new WWW(url); // Start a download of the given URL WWW www = new WWW(url); void On. GUI() // Wait for download to complete { yield return www; // Wait for download to complete GUI. Label(…); yield return www; } // assign string } texte = … // assign string } texte = System. Text. Encoding. UTF 7. Get. String(www. bytes); } void On. GUI() { GUI. Label(new Rect(10, 10, 300, 300), texte); } } } Comment récupérer du texte à partir d’un objet www ?
SERVEUR FTP Url : Login : Pass : ftp. kacem. fr kacem-uni unity 3 dlaval
SMARTFOXSERVER – Récupérez le dossier SFS 2 X-Lobby. zip et le décompresser – Ouvrir ce projet avec Unity 3 D – Modifier l’adresse du serveur en
SMARTFOXSERVER – Dans On. GUI() : if (GUI. Button(new Rect(100, 166, 100, 24), "Login") || (Event. current. type == Event. Type. key. Down && Event. current. character == 'n')) { Debug. Log("Sending login request"); smart. Fox. Send(new Login. Request(username, password, zone)); } //if (GUI. Button(new Rect(100, 166, 100, 24), "Login") || (Event. current. type == Event. Type. key. Down && Event. current. character == 'n')) { Debug. Log("Sending login request"); smart. Fox. Send(new Login. Request(“Toto", "", zone)); }
Décor • • Charger le décor principal Le placer au centre du monde Ajouter un personnage (Par exemple Lerpz) Lui affecter un Third. Person. Controller
Position • Envoyez la position de votre personnage toute les 5 secondes sous le format : « POSITION=2. 21: 54. 21: 51. 21288» Multipliez par 1000 chaque valeur et supprimez la partie flottante : « POSITION=2210: 54210: 51212»
Rotation • Ajoutez la rotation : « POSITION=2210: 54210: 51212; ROTATION=2121: 5213: 2542: 3665»
Lerpz • • • Ouvrir le projet Lerpz Faire un prefab du player Lerpz Faire un « export package » sur le prefab Revenir sur le projet en cours Faire un « import package »
Players Classe Net. Player public class Net. Player { public string player. Name; public Game. Object game. Object; public Vector 3 old. Position; new. Position; public Quaternion old. Rotation; new. Rotation; public Net. Player() { } } public class Lobby. GUI : Mono. Behaviour { static public Hashtable player. List = new Hashtable(); (…)
Players Enregistrer les Events void Start() { (…) smartfox. Add. Event. Listener(SFSEvent. USER_ENTER_ROOM, On. User. Enter. Room); smartfox. Add. Event. Listener(SFSEvent. USER_EXIT_ROOM, On. User. Leave. Room); } Ajouter des players public Game. Object new. Player. Model; public void On. User. Enter. Room(Base. Event evt) { User user = (User) evt. Params[“user”]; Debug. Log(“Le joueur “+ user. Name + “ s’est connecté”); // J’ajoute un nouveau player à ma liste Net. Player new. Player = new Net. Player(); void On. User. Leave. Room(Base. Event evt) new. Player. player. Name = user. Name; { new. Player. game. Object = (Game. Object) Instantiate(new. Player. Model); //Je supprime ce player à ma liste new. Player. game. Object. name = “Player ” + user. Name; } player. List[user. Name] = new. Player; }
Players public void On. User. Enter. Room(Base. Event evt) { User user = (User) evt. Params[“user”]; Debug. Log(“Le joueur “+ user. Name + “ s’est connecté”); // J’ajoute un nouveau player à ma liste Net. Player new. Player = new Net. Player(); new. Player. player. Name = user. Name; new. Player. game. Object = (Game. Object) Instantiate(new. Player. Model); new. Player. game. Object. name = “Player ” + user. Name; player. List[user. Name] = new. Player; } void On. User. Leave. Room(Base. Event evt) { User user = (User) evt. Params[“user”]; Debug. Log(“Le joueur “+ user. Name + “ s’est déconnecté”); //Je supprime ce player à ma liste Net. Player new. Player = (Net. Player) player. List[user. Name]; if (new. Player != null) { Destroy(new. Player. game. Object); player. List. Remove(user. Name); } }
Méthode Split Vector 3 Get. Vector 3(string translation) //translation = "1212: 123“ { string[] result = translation. Split(new char[] { ': ' }, 3); if (result. Length != 3) { return Vector 3. zero; } float x. Pos = Convert. To. Single(result[0]) / 1000. 0 f; float y. Pos = Convert. To. Single(result[1]) / 1000. 0 f; float z. Pos = Convert. To. Single(result[2]) / 1000. 0 f; return new Vector 3(x. Pos, y. Pos, z. Pos); }
Réception de la positon void On. Public. Message(Base. Event evt) { try { string message = (string) evt. Params["message"]; User sender = (User) evt. Params["sender"]; Net. Player net. Player = (Net. Player) player. List[sender. Name]; if (net. Player != null) { (…) net. Player. game. Object. transform. position = (…); } } catch (Exception ex) { Debug. Log("Exception handling public message: "+ex. Message+ex. Stack. Trace); } }
void On. Public. Message(Base. Event evt) { string message = (string) evt. Params["message"]; // message: “POSITION=1: 2: 3; ROTATION=1: 2: 3: 4" User sender = (User) evt. Params["sender"]; Net. Player net. Player = (Net. Player) player. List[sender. Name]; if (net. Player != null) { string[] operations = message. Split(new char[] { '; ' }); // operations[0]: “POSITION=1: 2: 3" // operations[1]: "ROTATION=1: 2: 3: 4" for (int i=0; i<operations. Length; i++) { string[] line = operations[i]. Split(new char[] { '=' }); // line[0]: “POSITION" // line[1]: "1: 2: 3" switch(line[0]) { case "POSITION": net. Player. game. Object. transform. position = Get. Vector 3(line[1]); break; case "ROTATION": net. Player. game. Object. transform. rotation = Get. Quaternion(line[1]); break; } } }
void On. Public. Message(Base. Event evt) { string message = (string) evt. Params["message"]; // message: "TRANSLATION=1: 2: 3; ROTATION=1: 2: 3: 4" User sender = (User) evt. Params["sender"]; Net. Player net. Player = (Net. Player) player. List[sender. Name]; if (net. Player != null) { string[] operations = message. Split(new char[] { '; ' }); // operations[0]: "TRANSLATION=1: 2: 3" // operations[1]: "ROTATION=1: 2: 3: 4" for (int i=0; i<operations. Length; i++) { string[] line = operations[i]. Split(new char[] { '=' }); // line[0]: "TRANSLATION" // line[1]: "1: 2: 3" switch(line[0]) { case "POSITION": net. Player. old. Position net. Player. new. Position break; case "ROTATION": net. Player. old. Rotation net. Player. new. Rotation break; } } } = net. Player. game. Object. transform. position; = Get. Vector 3(line[1]); = net. Player. game. Object. transform. rotation; = Get. Quaternion(line[1]);
Chapitre 5
Memory • Génération d’un plateau de X cartes en 3 D • Lorsqu’on clique sur une carte, elle se retourne • Lorsqu’on clic sur 2 cartes identiques, la paire disparait. • Le score est le temps qu’on a mis pour résoudre le plateau complet.
Case brulante • Génération d’un plateau de X cases (niveau prédéfini) • Lorsqu’on marche sur une case, elle tombe (au bout de 2 sec) • Il faut faire tomber toutes les cases pour gagner le niveau et passer au suivant,
Ce que vous voulez
Critères d’évaluations • • • Le jeu se lance. / Il est en 3 D On comprends le jeu / On peut finir le jeu. Présence d’un menu clair. Utilisation des GUIStyle. Il y a plusieurs niveaux (avec des différences fonctionnelles) ? Affichage des scores pendant et après. Sauver en Player. Prefs. Jouabilité / intérêt Fluidité / temps de chargement Qualité du code / Taille du fichier à télécharger. Qualité visuelle / Cohérence générale. Difficulté technique / Choix techniques
- Slides: 94