<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Computer Graphics | Étienne Peillard</title><link>https://www.etiennepeillard.com/fr/category/computer-graphics/</link><atom:link href="https://www.etiennepeillard.com/fr/category/computer-graphics/index.xml" rel="self" type="application/rss+xml"/><description>Computer Graphics</description><generator>Wowchemy (https://wowchemy.com)</generator><lastBuildDate>Mon, 09 Feb 2026 00:00:00 +0000</lastBuildDate><image><url>https://www.etiennepeillard.com/media/sharing.png</url><title>Computer Graphics</title><link>https://www.etiennepeillard.com/fr/category/computer-graphics/</link></image><item><title>TP — Rendu 3D : diorama stylisé</title><link>https://www.etiennepeillard.com/fr/teaching/lab/tp-rendering/</link><pubDate>Mon, 09 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.etiennepeillard.com/fr/teaching/lab/tp-rendering/</guid><description>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="alt text" srcset="
/fr/teaching/lab/tp-rendering/image_hu7dd5aef356258fbf43cea35437bc6427_896510_f08c89c3dbed374e7e7f06c6bec96ad9.webp 400w,
/fr/teaching/lab/tp-rendering/image_hu7dd5aef356258fbf43cea35437bc6427_896510_db6fd58d848071eb6f19061ff6d231f5.webp 760w,
/fr/teaching/lab/tp-rendering/image_hu7dd5aef356258fbf43cea35437bc6427_896510_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/tp-rendering/image_hu7dd5aef356258fbf43cea35437bc6427_896510_f08c89c3dbed374e7e7f06c6bec96ad9.webp"
width="760"
height="189"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="-objectif-du-tp">🎯 Objectif du TP&lt;/h2>
&lt;p>Réaliser une &lt;strong>scène type &lt;em>diorama&lt;/em>&lt;/strong> (petit monde en miniature) sous &lt;strong>Unity avec l’URP&lt;/strong>, en travaillant :&lt;/p>
&lt;ul>
&lt;li>la &lt;strong>composition visuelle&lt;/strong> (mise en scène, lisibilité, point focal),&lt;/li>
&lt;li>le &lt;strong>rendu&lt;/strong> (lumières, matériaux, post-processing),&lt;/li>
&lt;li>et une première dimension &lt;strong>tech-art&lt;/strong> (Shader Graph et/ou VFX).&lt;/li>
&lt;/ul>
&lt;p>Le rendu final doit être &lt;strong>cohérent visuellement&lt;/strong> : même si vous utilisez des assets externes, vous devrez harmoniser leurs matériaux et l’ambiance lumineuse.&lt;/p>
&lt;hr>
&lt;h2 id="-contraintes-obligatoires-socle-commun">📌 Contraintes obligatoires (socle commun)&lt;/h2>
&lt;p>Votre scène &lt;strong>doit impérativement inclure&lt;/strong> les éléments suivants :&lt;/p>
&lt;h3 id="1-composition--environnement">1) Composition / environnement&lt;/h3>
&lt;ul>
&lt;li>Une scène lisible de type &lt;em>diorama&lt;/em> (miniature, cadre clair, point focal).&lt;/li>
&lt;li>Vous pouvez utiliser des assets gratuits (Asset Store, Kenney, Poly Pizza, etc.),&lt;br>
&lt;strong>mais vous devez modifier les matériaux pour assurer une cohérence visuelle&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;h3 id="2-lumières">2) Lumières&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Au minimum 3 sources lumineuses distinctes&lt;/strong>, par exemple :
&lt;ul>
&lt;li>Directional Light (soleil),&lt;/li>
&lt;li>Spot Light (mise en valeur d’un objet),&lt;/li>
&lt;li>Point Light (ambiance locale).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Attendu : une intention claire (ambiance chaude/froide, contrastes, hiérarchie visuelle).&lt;/li>
&lt;/ul>
&lt;h3 id="3-skybox--environnement">3) Skybox / environnement&lt;/h3>
&lt;ul>
&lt;li>Une &lt;strong>Skybox&lt;/strong> (HDRI ou procédurale).&lt;/li>
&lt;li>Réglages d’environnement (Ambient Light, Reflections).&lt;/li>
&lt;/ul>
&lt;h3 id="4-effets-visuels">4) Effets visuels&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Au moins 1 Particle System (Shuriken)&lt;/strong> intégré à la scène&lt;br>
(fumée, poussière, neige, lucioles, étincelles, bulles…).&lt;/li>
&lt;li>&lt;strong>Au moins 1 Volume URP de post-processing&lt;/strong>, avec au minimum :
&lt;ul>
&lt;li>Bloom &lt;strong>ou&lt;/strong>&lt;/li>
&lt;li>Color Adjustments.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="5-matériaux-et-shaders">5) Matériaux et shaders&lt;/h3>
&lt;ul>
&lt;li>Utiliser &lt;strong>au moins un Material standard URP (Lit)&lt;/strong>.
&lt;ul>
&lt;li>Vous pouvez ici utiliser les différentes map de textures (albedo, normal, metallic, etc.) pour enrichir le rendu.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Créer &lt;strong>au moins un Shader personnalisé avec Shader Graph&lt;/strong>, et l’appliquer à un objet de la scène.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="-options-à-la-carte">🧩 Options à la carte&lt;/h2>
&lt;p>Ces options permettent d’aller plus loin selon votre niveau et votre créativité.&lt;/p>
&lt;h3 id="a--lighting-avancé-recommandé">A — Lighting avancé (recommandé)&lt;/h3>
&lt;ul>
&lt;li>Lighting &lt;strong>Baked ou Mixed&lt;/strong>.&lt;/li>
&lt;li>Utilisation de &lt;strong>Light Probes&lt;/strong> et/ou &lt;strong>Reflection Probes&lt;/strong> pour améliorer le rendu.&lt;/li>
&lt;/ul>
&lt;h3 id="b--vfx-graph-ou-particules-avancées">B — VFX Graph (ou particules avancées)&lt;/h3>
&lt;ul>
&lt;li>Un effet avec &lt;strong>VFX Graph&lt;/strong> (si compatible avec votre version Unity),&lt;br>
&lt;strong>ou&lt;/strong> un Particle System avancé (collision, noise, trails, forces).&lt;/li>
&lt;/ul>
&lt;h3 id="c--cinématique-timeline">C — Cinématique (Timeline)&lt;/h3>
&lt;ul>
&lt;li>Une mini-cinématique de &lt;strong>5 à 10 secondes&lt;/strong> :
&lt;ul>
&lt;li>mouvement de caméra,&lt;/li>
&lt;li>reveal du point focal,&lt;/li>
&lt;li>variation de lumière ou d’effet.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="d--modélisation-in-editor-probuilder">D — Modélisation in-editor (ProBuilder)&lt;/h3>
&lt;ul>
&lt;li>Créer &lt;strong>au moins deux éléments de décor&lt;/strong> avec ProBuilder&lt;br>
(socle, rocher stylisé, arche, mur, pont, plateforme…).&lt;/li>
&lt;/ul>
&lt;h3 id="e--interaction-simple">E — Interaction simple&lt;/h3>
&lt;p>Implémenter &lt;strong>une interaction basique&lt;/strong>, par exemple :&lt;/p>
&lt;ul>
&lt;li>bascule jour/nuit,&lt;/li>
&lt;li>changement de palette de couleurs,&lt;/li>
&lt;li>activation/désactivation de particules,&lt;/li>
&lt;li>ouverture de porte,&lt;/li>
&lt;li>allumage d’une lanterne.&lt;/li>
&lt;/ul>
&lt;h3 id="f--ambiance-sonore">F — Ambiance sonore&lt;/h3>
&lt;ul>
&lt;li>Ajouter :
&lt;ul>
&lt;li>une ambiance sonore (vent, forêt, mer, usine, ville…),&lt;/li>
&lt;li>au moins un effet sonore localisé en 3D.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="-idées-de-thèmes-au-choix">🎨 Idées de thèmes (au choix)&lt;/h2>
&lt;p>Pour éviter des scènes trop similaires, vous pouvez vous inspirer de ces pistes :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Atelier miniature&lt;/strong> (horloger, alchimiste, bricoleur).&lt;/li>
&lt;li>&lt;strong>Ruines dans une bulle&lt;/strong> (temple, statues, végétation).&lt;/li>
&lt;li>&lt;strong>Station de métro miniature&lt;/strong> (néons, fumée, reflets).&lt;/li>
&lt;li>&lt;strong>Cabane enneigée&lt;/strong> (neige + lumière intérieure chaude).&lt;/li>
&lt;li>&lt;strong>Fond marin stylisé&lt;/strong> (bulles, caustiques simulées, particules).&lt;/li>
&lt;/ul>
&lt;p>Vous pouvez aussi proposer votre propre thème, tant qu’il respecte l’esprit &lt;em>diorama&lt;/em>.&lt;/p>
&lt;hr>
&lt;h2 id="-livrables-attendus">📦 Livrables attendus&lt;/h2>
&lt;h3 id="1-projet-unity">1) Projet Unity&lt;/h3>
&lt;ul>
&lt;li>Scène principale nommée : &lt;code>Diorama.unity&lt;/code>&lt;/li>
&lt;li>Projet fonctionnel en &lt;strong>URP&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;h3 id="2-readme-1-page-max">2) README (1 page max)&lt;/h3>
&lt;p>À inclure dans le projet (Markdown ou PDF) :&lt;/p>
&lt;ul>
&lt;li>Titre et thème du diorama,&lt;/li>
&lt;li>Liste des 5 contraintes obligatoires (cochées),&lt;/li>
&lt;li>Liste des 3 options choisies (avec courte justification),&lt;/li>
&lt;li>Sources des assets utilisés (liens + licences).&lt;/li>
&lt;/ul>
&lt;h3 id="3-image-ou-vidéo-de-présentation">3) Image ou vidéo de présentation&lt;/h3>
&lt;ul>
&lt;li>un plan fixe “beau rendu”,&lt;/li>
&lt;li>un bref mouvement de caméra (pan, rotation, ou travelling).&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="-barème-indicatif">🧮 Barème indicatif&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Critère&lt;/th>
&lt;th>Pondération&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Composition &amp;amp; direction artistique&lt;/td>
&lt;td>&lt;strong>30 %&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Cohérence des matériaux&lt;/td>
&lt;td>&lt;strong>25 %&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Lighting, Skybox &amp;amp; Post-process&lt;/td>
&lt;td>&lt;strong>20 %&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Shader Graph (qualité + intégration)&lt;/td>
&lt;td>&lt;strong>15 %&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Options choisies (pertinence)&lt;/td>
&lt;td>&lt;strong>10 %&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Bonus&lt;/strong> : polish général (petites animations, détails, optimisation simple).&lt;/p>
&lt;hr>
&lt;h2 id="-ressources-utiles">📚 Ressources utiles&lt;/h2>
&lt;h3 id="assets-gratuits">Assets gratuits&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>3d textures&lt;/strong>: &lt;a href="https://3dtextures.me" target="_blank" rel="noopener">https://3dtextures.me&lt;/a>&lt;/li>
&lt;li>&lt;strong>Kenney (CC0)&lt;/strong> : &lt;a href="https://kenney.nl" target="_blank" rel="noopener">https://kenney.nl&lt;/a>&lt;/li>
&lt;li>&lt;strong>Poly Pizza&lt;/strong> : &lt;a href="https://poly.pizza" target="_blank" rel="noopener">https://poly.pizza&lt;/a>&lt;/li>
&lt;li>&lt;strong>Poly Haven (HDRI Skyboxes)&lt;/strong> : &lt;a href="https://polyhaven.com" target="_blank" rel="noopener">https://polyhaven.com&lt;/a>&lt;/li>
&lt;li>&lt;strong>Unity Asset Store (Top Free)&lt;/strong> : &lt;a href="https://assetstore.unity.com/top-assets/top-free" target="_blank" rel="noopener">https://assetstore.unity.com/top-assets/top-free&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="shader-graph">Shader Graph&lt;/h3>
&lt;ul>
&lt;li>Unity Learn – prise en main :&lt;br>
&lt;a href="https://learn.unity.com/tutorial/get-started-with-shader-graph" target="_blank" rel="noopener">https://learn.unity.com/tutorial/get-started-with-shader-graph&lt;/a>&lt;/li>
&lt;li>Exemples de shaders :
&lt;a href="https://www.youtube.com/playlist?list=PLsaDw3p1XpJiPp3v5gUyxuWkmUn3eB731" target="_blank" rel="noopener">https://www.youtube.com/playlist?list=PLsaDw3p1XpJiPp3v5gUyxuWkmUn3eB731&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="post-processing-urp">Post-processing URP&lt;/h3>
&lt;ul>
&lt;li>Documentation officielle :&lt;br>
&lt;a href="https://docs.unity3d.com/Manual/urp-integration-with-post-processing.html" target="_blank" rel="noopener">https://docs.unity3d.com/Manual/urp-integration-with-post-processing.html&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="particles--vfx">Particles / VFX&lt;/h3>
&lt;ul>
&lt;li>VFX Graph (Unity 6) :&lt;br>
&lt;a href="https://unity.com/resources/creating-advanced-vfx-unity6" target="_blank" rel="noopener">https://unity.com/resources/creating-advanced-vfx-unity6&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="lighting-baked-probes">Lighting (Baked, Probes)&lt;/h3>
&lt;ul>
&lt;li>Reflection Probes :&lt;br>
&lt;a href="https://docs.unity3d.com/Manual/class-ReflectionProbe.html" target="_blank" rel="noopener">https://docs.unity3d.com/Manual/class-ReflectionProbe.html&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="probuilder">ProBuilder&lt;/h3>
&lt;ul>
&lt;li>Documentation :&lt;br>
&lt;a href="https://docs.unity3d.com/Packages/com.unity.probuilder" target="_blank" rel="noopener">https://docs.unity3d.com/Packages/com.unity.probuilder&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="timeline--cinématique">Timeline / Cinématique&lt;/h3>
&lt;ul>
&lt;li>Introduction officielle :&lt;br>
&lt;a href="https://unity.com/fr/blog/games/first-guide-animation-in-unity" target="_blank" rel="noopener">https://unity.com/fr/blog/games/first-guide-animation-in-unity&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>TP — Les bases d’Unity 3D</title><link>https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/</link><pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/</guid><description>&lt;section class="unity-intro" aria-label="Présentation du TP">
&lt;div class="unity-intro__top">
&lt;span class="unity-intro__eyebrow">Premiers pas · Création 3D&lt;/span>
&lt;img class="unity-intro__logo" src="images/figure-01.png" alt="Unity" width="345" height="146">
&lt;/div>
&lt;dl class="unity-intro__facts">
&lt;div>&lt;dt>Durée&lt;/dt>&lt;dd>2–3 heures&lt;/dd>&lt;/div>
&lt;div>&lt;dt>Environnement&lt;/dt>&lt;dd>Unity 6.3 LTS · URP&lt;/dd>&lt;/div>
&lt;div>&lt;dt>Niveau&lt;/dt>&lt;dd>Débutant Unity&lt;/dd>&lt;/div>
&lt;/dl>
&lt;div class="unity-intro__body">&lt;p>Une première initiation à Unity pour des étudiants à l’aise en informatique, sans expérience du moteur. Vous construirez une scène de cubes, ajouterez physique et interactions, naviguerez à la première personne, lancerez des objets, importerez une voiture et créerez un exécutable.&lt;/p>
&lt;p>&lt;strong>Unity 6.3 LTS (6000.3) doit être installé.&lt;/strong> La création du projet, l’installation des packages et l’import des ressources se font pendant la séance. Le temps nécessaire dépendra de votre expérience en C#.&lt;/p>
&lt;/div>
&lt;div class="unity-intro__links">
&lt;a class="unity-intro__card" href="resources-unity63.zip">
&lt;span class="unity-intro__card-label">Fichiers du TP&lt;/span>
&lt;strong>Télécharger les ressources &lt;span aria-hidden="true">↓&lt;/span>&lt;/strong>
&lt;span>Texture du sol et modèle de voiture · ZIP&lt;/span>
&lt;/a>
&lt;a class="unity-intro__card" href="../../tutorial/rapport-tp/">
&lt;span class="unity-intro__card-label">À consulter&lt;/span>
&lt;strong>Consignes du compte rendu &lt;span aria-hidden="true">↗&lt;/span>&lt;/strong>
&lt;span>Attendus et canevas du rapport&lt;/span>
&lt;/a>
&lt;/div>
&lt;div class="unity-intro__references">
&lt;span>Documentation&lt;/span>
&lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/">Manuel Unity 6.3&lt;/a>
&lt;a href="https://learn.unity.com/">Unity Learn&lt;/a>
&lt;/div>
&lt;p class="unity-intro__campus">&lt;span>Brest uniquement&lt;/span> &lt;a href="../../tutorial/unity-instructions-pc-ecole/">Configurer les PC de l’école &lt;span aria-hidden="true">→&lt;/span>&lt;/a>&lt;/p>
&lt;details class="unity-intro__help">
&lt;summary>Des définitions au fil du TP&lt;/summary>
&lt;p>Les termes soulignés en pointillés ont une définition : survolez-les ou cliquez dessus. Vous pouvez aussi les atteindre avec Tab et utiliser Entrée ou Espace ; Échap ferme l’infobulle.&lt;/p>
&lt;/details>
&lt;details class="unity-intro__outline">
&lt;summary>Plan du TP&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#préparer-le-projet">Préparer le projet&lt;/a>&lt;/li>
&lt;li>&lt;a href="#léditeur-dunity-3d">L’éditeur d’Unity 3D&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#les-notions-fondamentales">Les notions fondamentales&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#créer-une-scène-simple">Créer une scène simple&lt;/a>&lt;/li>
&lt;li>&lt;a href="#animer-un-objet-de-la-scène">Animer un objet de la scène&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#écrire-rotatecube">Écrire RotateCube&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#gestion-des-interactions">Gestion des interactions&lt;/a>&lt;/li>
&lt;li>&lt;a href="#programmation-dinteraction-simple-avec-la-souris">Programmation d’interaction simple avec la souris&lt;/a>&lt;/li>
&lt;li>&lt;a href="#navigation-en-réutilisant-des-scripts-dinteraction-claviersouris">Navigation en réutilisant des scripts d’interaction clavier/souris&lt;/a>&lt;/li>
&lt;li>&lt;a href="#création-dynamique-dobjets">Création dynamique d’objets&lt;/a>&lt;/li>
&lt;li>&lt;a href="#charger-une-géométrie">Charger une géométrie&lt;/a>&lt;/li>
&lt;li>&lt;a href="#créer-un-exécutable-pour-la-scène">Créer un exécutable pour la scène&lt;/a>&lt;/li>
&lt;li>&lt;a href="#pour-aller-plus-loin">Pour aller plus loin&lt;/a>&lt;/li>
&lt;li>&lt;a href="#ressources">Ressources&lt;/a>&lt;/li>
&lt;li>&lt;a href="#en-cas-de-blocage">En cas de blocage&lt;/a>&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;/section>
&lt;h2 id="préparer-le-projet">Préparer le projet&lt;/h2>
&lt;ol>
&lt;li>Dans &lt;button type="button" class="unity-term" popovertarget="unity-term-1" popovertargetaction="show" aria-describedby="unity-term-1">Unity Hub&lt;/button>&lt;span id="unity-term-1" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Unity Hub&lt;/strong>&lt;span>Application qui permet de créer et ouvrir des projets Unity et de gérer les versions de l’éditeur installées.&lt;/span>&lt;/span>
, sélectionnez &lt;strong>6.3 LTS&lt;/strong> et créez un projet &lt;strong>Universal 3D&lt;/strong> (&lt;button type="button" class="unity-term" popovertarget="unity-term-2" popovertargetaction="show" aria-describedby="unity-term-2">URP&lt;/button>&lt;span id="unity-term-2" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>URP&lt;/strong>&lt;span>Universal Render Pipeline : système de rendu de Unity qui transforme la scène en images. Ses matériaux doivent utiliser des shaders compatibles URP.&lt;/span>&lt;/span>
). Utilisez le même patch &lt;code>6000.3.xf1&lt;/code> pour toute la séance. Les &lt;button type="button" class="unity-term" popovertarget="unity-term-3" popovertargetaction="show" aria-describedby="unity-term-3">matériaux&lt;/button>&lt;span id="unity-term-3" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Matériau&lt;/strong>&lt;span>Asset qui décrit l’apparence d’une surface en combinant un shader et ses paramètres, comme la couleur et les textures.&lt;/span>&lt;/span>
et le contrôleur utilisés ici sont prévus pour URP.&lt;/li>
&lt;li>Les &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-4" popovertargetaction="show" aria-describedby="unity-term-4">assets&lt;/button>&lt;span id="unity-term-4" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Asset&lt;/strong>&lt;span>Ressource enregistrée dans le projet : scène, script, texture, matériau, modèle ou prefab. Elle peut être utilisée par plusieurs objets.&lt;/span>&lt;/span>
&lt;/strong> sont les ressources de votre projet : scènes, &lt;button type="button" class="unity-term" popovertarget="unity-term-5" popovertargetaction="show" aria-describedby="unity-term-5">scripts&lt;/button>&lt;span id="unity-term-5" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Script&lt;/strong>&lt;span>Fichier de code C# du projet. Un script dérivant de MonoBehaviour peut être attaché comme composant à un GameObject.&lt;/span>&lt;/span>
, matériaux, &lt;button type="button" class="unity-term" popovertarget="unity-term-6" popovertargetaction="show" aria-describedby="unity-term-6">textures&lt;/button>&lt;span id="unity-term-6" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Texture&lt;/strong>&lt;span>Image utilisée par un matériau pour détailler une surface : couleur, relief apparent, etc. Une texture seule ne définit pas tout le rendu.&lt;/span>&lt;/span>
, &lt;button type="button" class="unity-term" popovertarget="unity-term-7" popovertargetaction="show" aria-describedby="unity-term-7">modèles 3D&lt;/button>&lt;span id="unity-term-7" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Modèle 3D&lt;/strong>&lt;span>Ressource importée contenant une géométrie et éventuellement des matériaux, une hiérarchie ou des animations.&lt;/span>&lt;/span>
et &lt;button type="button" class="unity-term" popovertarget="unity-term-8" popovertargetaction="show" aria-describedby="unity-term-8">prefabs&lt;/button>&lt;span id="unity-term-8" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Prefab&lt;/strong>&lt;span>Asset servant de modèle réutilisable de GameObject, avec ses composants et enfants. Ses instances héritent des modifications du modèle, sauf leurs réglages remplacés localement.&lt;/span>&lt;/span>
. Ils sont regroupés dans le dossier &lt;strong>Assets&lt;/strong>, visible dans la fenêtre &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-9" popovertargetaction="show" aria-describedby="unity-term-9">Project&lt;/button>&lt;span id="unity-term-9" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Project&lt;/strong>&lt;span>Fenêtre de l’éditeur affichant les fichiers et assets du projet. Elle se distingue de Hierarchy, qui montre les objets de la scène.&lt;/span>&lt;/span>
&lt;/strong>. Pour les organiser, créez les sous-dossiers &lt;code>Scenes&lt;/code>, &lt;code>Materials&lt;/code>, &lt;code>Textures&lt;/code>, &lt;code>Prefabs&lt;/code> et &lt;code>Scripts&lt;/code> avec &lt;strong>clic droit dans Assets &amp;gt; Create &amp;gt; Folder&lt;/strong> ; utilisez &lt;code>Scenes&lt;/code> s’il existe déjà. Dans Project, retrouvez la scène ouverte (généralement &lt;code>SampleScene&lt;/code>), renommez-la &lt;strong>UnityBasics&lt;/strong> avec &lt;strong>Rename&lt;/strong> (ou F2), puis déplacez-la dans &lt;code>Assets/Scenes&lt;/code> si nécessaire. Sauvegardez la scène avec &lt;strong>Ctrl+S&lt;/strong>.&lt;/li>
&lt;li>Ouvrez &lt;strong>Window &amp;gt; Package Management &amp;gt; &lt;button type="button" class="unity-term" popovertarget="unity-term-10" popovertargetaction="show" aria-describedby="unity-term-10">Package Manager&lt;/button>&lt;span id="unity-term-10" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Package Manager&lt;/strong>&lt;span>Fenêtre qui permet de rechercher, installer et gérer les packages et d’importer les assets de votre compte.&lt;/span>&lt;/span>
&lt;/strong>. Dans &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-11" popovertargetaction="show" aria-describedby="unity-term-11">Unity Registry&lt;/button>&lt;span id="unity-term-11" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Unity Registry&lt;/strong>&lt;span>Catalogue de packages publié par Unity, consultable dans le Package Manager.&lt;/span>&lt;/span>
&lt;/strong>, recherchez &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-12" popovertargetaction="show" aria-describedby="unity-term-12">Input System&lt;/button>&lt;span id="unity-term-12" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Input System&lt;/strong>&lt;span>Package qui reçoit les entrées clavier, souris ou manette et les associe à des actions de l’application.&lt;/span>&lt;/span>
&lt;/strong> (&lt;code>com.unity.inputsystem&lt;/code>) et cliquez sur &lt;strong>Install&lt;/strong> s’il n’est pas installé. La version utilisée lors du test du TP est &lt;strong>1.20.0&lt;/strong>. Dans &lt;strong>Edit &amp;gt; Project Settings &amp;gt; Player &amp;gt; Other Settings &amp;gt; Configuration &amp;gt; &lt;button type="button" class="unity-term" popovertarget="unity-term-13" popovertargetaction="show" aria-describedby="unity-term-13">Active Input Handling&lt;/button>&lt;span id="unity-term-13" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Active Input Handling&lt;/strong>&lt;span>Réglage du projet qui choisit les systèmes d’entrées activés : Input System, ancien Input Manager ou les deux.&lt;/span>&lt;/span>
&lt;/strong>, choisissez &lt;strong>Input System Package (New)&lt;/strong> &lt;strong>si ce réglage n’est pas déjà sélectionné&lt;/strong>, puis acceptez le redémarrage demandé. Dans le Package Manager, sous &lt;strong>In Project&lt;/strong>, vérifiez que &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-14" popovertargetaction="show" aria-describedby="unity-term-14">Unity UI&lt;/button>&lt;span id="unity-term-14" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Unity UI / uGUI&lt;/strong>&lt;span>Système d’interface de Unity basé sur les GameObjects. Il fournit aussi l’EventSystem et les interfaces d’événements de pointeur utilisées ici.&lt;/span>&lt;/span>
&lt;/strong> (&lt;code>com.unity.ugui&lt;/code>) est installé : ce package fournit l’&lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-15" popovertargetaction="show" aria-describedby="unity-term-15">EventSystem&lt;/button>&lt;span id="unity-term-15" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>EventSystem&lt;/strong>&lt;span>Composant qui distribue les événements d’interaction aux objets concernés, avec l’aide d’un module d’entrées et de raycasters.&lt;/span>&lt;/span>
&lt;/strong>, le &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-16" popovertargetaction="show" aria-describedby="unity-term-16">Physics Raycaster&lt;/button>&lt;span id="unity-term-16" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Physics Raycaster&lt;/strong>&lt;span>Composant de caméra qui identifie les colliders 3D sous le pointeur et fournit ces résultats à l’EventSystem.&lt;/span>&lt;/span>
&lt;/strong> et les interfaces de clic/survol utilisés plus loin. S’il manque, recherchez-le dans &lt;strong>Unity Registry&lt;/strong> et installez-le.&lt;/li>
&lt;li>Ajoutez le &lt;a href="https://assetstore.unity.com/packages/3d/characters/first-person-third-person-character-controllers-196526" target="_blank" rel="noopener">contrôleur officiel première/troisième personne&lt;/a> à votre compte puis importez-le via &lt;strong>My Assets&lt;/strong> dans le Package Manager. Acceptez l’installation de ses dépendances lorsqu’elle est proposée, puis revenez à &lt;code>UnityBasics&lt;/code>.&lt;/li>
&lt;li>Téléchargez et décompressez les &lt;a href="resources-unity63.zip">ressources du TP (&lt;code>resources-unity63.zip&lt;/code>)&lt;/a>. Depuis l’explorateur de fichiers, glissez &lt;code>grid_grey.png&lt;/code> dans &lt;code>Assets/Textures&lt;/code> dans la fenêtre Project. L’archive contient aussi &lt;code>Ford_Mondeo.zip&lt;/code> : décompressez-la pour obtenir le dossier &lt;code>Ford_Mondeo&lt;/code>, contenant &lt;code>car.obj&lt;/code>, &lt;code>car.mtl&lt;/code> et les textures &lt;code>.tga&lt;/code>. Gardez ce dossier pour l’activité &lt;strong>Charger une géométrie&lt;/strong>, où vous l’importerez en entier dans Unity.&lt;/li>
&lt;/ol>
&lt;h2 id="léditeur-dunity-3d">L’éditeur d’Unity 3D&lt;/h2>
&lt;p>Une scène du &lt;button type="button" class="unity-term" popovertarget="unity-term-17" popovertargetaction="show" aria-describedby="unity-term-17">template&lt;/button>&lt;span id="unity-term-17" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Template&lt;/strong>&lt;span>Modèle de départ qui crée un projet avec des packages et des réglages déjà configurés.&lt;/span>&lt;/span>
contient généralement &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-18" popovertargetaction="show" aria-describedby="unity-term-18">Main Camera&lt;/button>&lt;span id="unity-term-18" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Caméra&lt;/strong>&lt;span>Objet muni d’un composant Camera qui rend une vue de la scène. La navigation dans Scene n’est pas la même chose que cette vue de jeu.&lt;/span>&lt;/span>
&lt;/strong>, &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-19" popovertargetaction="show" aria-describedby="unity-term-19">Directional Light&lt;/button>&lt;span id="unity-term-19" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Directional Light&lt;/strong>&lt;span>Lumière qui éclaire selon une direction uniforme, comme un soleil très éloigné.&lt;/span>&lt;/span>
&lt;/strong> et éventuellement un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-20" popovertargetaction="show" aria-describedby="unity-term-20">Global Volume&lt;/button>&lt;span id="unity-term-20" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Global Volume&lt;/strong>&lt;span>Objet qui applique des réglages de rendu, notamment des effets de post-traitement, à l’ensemble de la scène selon sa configuration.&lt;/span>&lt;/span>
&lt;/strong> pour le rendu URP. La disposition des fenêtres peut varier.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Repères des fenêtres de l’éditeur" srcset="
/fr/teaching/lab/intro-unity/images/unity63-editor-numbered_hud0ac6e7e6d72c5576d38b230060eecc7_1472125_8ee180c96def1483d4b4de322d35a05f.webp 400w,
/fr/teaching/lab/intro-unity/images/unity63-editor-numbered_hud0ac6e7e6d72c5576d38b230060eecc7_1472125_037882c13ba931ca2b32db7d1027ae57.webp 760w,
/fr/teaching/lab/intro-unity/images/unity63-editor-numbered_hud0ac6e7e6d72c5576d38b230060eecc7_1472125_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/unity63-editor-numbered_hud0ac6e7e6d72c5576d38b230060eecc7_1472125_8ee180c96def1483d4b4de322d35a05f.webp"
width="760"
height="616"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>&lt;em>Capture de Unity 6.3 LTS. Les repères 6 et 7 désignent les onglets &lt;button type="button" class="unity-term" popovertarget="unity-term-21" popovertargetaction="show" aria-describedby="unity-term-21">Game&lt;/button>&lt;span id="unity-term-21" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Game&lt;/strong>&lt;span>Fenêtre affichant l’image produite par les caméras du jeu ; on y teste les interactions de l’application.&lt;/span>&lt;/span>
et &lt;button type="button" class="unity-term" popovertarget="unity-term-22" popovertargetaction="show" aria-describedby="unity-term-22">Console&lt;/button>&lt;span id="unity-term-22" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Console&lt;/strong>&lt;span>Fenêtre affichant les logs, avertissements et erreurs, notamment les erreurs de compilation C#.&lt;/span>&lt;/span>
; cliquez dessus pour afficher leur contenu.&lt;/em>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Repère&lt;/th>
&lt;th>Fenêtre&lt;/th>
&lt;th>Rôle&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>&lt;button type="button" class="unity-term" popovertarget="unity-term-23" popovertargetaction="show" aria-describedby="unity-term-23">Scene&lt;/button>&lt;span id="unity-term-23" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Scene&lt;/strong>&lt;span>Vue de travail qui permet d’inspecter et modifier la scène sans dépendre de la caméra du jeu.&lt;/span>&lt;/span>
&lt;/td>
&lt;td>Naviguer et manipuler les objets de la scène.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2&lt;/td>
&lt;td>&lt;button type="button" class="unity-term" popovertarget="unity-term-24" popovertargetaction="show" aria-describedby="unity-term-24">Hierarchy&lt;/button>&lt;span id="unity-term-24" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Hierarchy&lt;/strong>&lt;span>Fenêtre qui liste les GameObjects de la scène et leurs relations parent/enfant.&lt;/span>&lt;/span>
&lt;/td>
&lt;td>Voir les &lt;button type="button" class="unity-term" popovertarget="unity-term-25" popovertargetaction="show" aria-describedby="unity-term-25">GameObjects&lt;/button>&lt;span id="unity-term-25" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>GameObject&lt;/strong>&lt;span>Objet de base de la scène. Ses composants lui donnent ses fonctions : affichage, physique, lumière, script, etc.&lt;/span>&lt;/span>
et leurs relations parent/enfant.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>&lt;button type="button" class="unity-term" popovertarget="unity-term-26" popovertargetaction="show" aria-describedby="unity-term-26">Inspector&lt;/button>&lt;span id="unity-term-26" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Inspector&lt;/strong>&lt;span>Fenêtre qui affiche les composants ou les paramètres d’import de l’élément sélectionné et permet de les modifier.&lt;/span>&lt;/span>
&lt;/td>
&lt;td>Voir et modifier tous les &lt;button type="button" class="unity-term" popovertarget="unity-term-27" popovertargetaction="show" aria-describedby="unity-term-27">composants&lt;/button>&lt;span id="unity-term-27" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Composant&lt;/strong>&lt;span>Élément attaché à un GameObject qui lui ajoute une propriété ou un comportement. Un même objet peut en posséder plusieurs.&lt;/span>&lt;/span>
, y compris les scripts.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>4&lt;/td>
&lt;td>Project&lt;/td>
&lt;td>Voir les assets : scènes, textures, matériaux, prefabs, scripts…&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>&lt;button type="button" class="unity-term" popovertarget="unity-term-28" popovertargetaction="show" aria-describedby="unity-term-28">Play&lt;/button>&lt;span id="unity-term-28" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Play mode&lt;/strong>&lt;span>Mode qui exécute l’application dans l’éditeur. Les changements de scène effectués pendant l’exécution sont normalement perdus à l’arrêt.&lt;/span>&lt;/span>
/ Pause / Step&lt;/td>
&lt;td>Exécuter, suspendre et avancer image par image.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>6&lt;/td>
&lt;td>Game&lt;/td>
&lt;td>Voir le résultat rendu par la caméra.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>7&lt;/td>
&lt;td>Console&lt;/td>
&lt;td>Lire les messages, avertissements et erreurs.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="les-notions-fondamentales">Les notions fondamentales&lt;/h3>
&lt;p>Avant de manipuler les objets, prenez le temps de comprendre les liens entre les ressources du projet, les objets de la scène et leurs composants. Les encarts suivants servent de repères pour toute la séance.&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-29">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-29" class="unity-concept__title">Le projet, les assets et les instances&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Le &lt;strong>projet&lt;/strong> contient les ressources et les réglages de l’application. Un &lt;strong>asset&lt;/strong> est une ressource enregistrée, visible dans &lt;strong>Project&lt;/strong> : texture, matériau, script, modèle 3D ou scène.&lt;/p>
&lt;p>Une &lt;strong>instance&lt;/strong> est un exemplaire placé dans la scène. Les douze cubes peuvent partager un matériau : modifier cet asset change leur apparence à tous ; déplacer un cube dans &lt;strong>Hierarchy&lt;/strong> ne déplace que lui.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-30">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-30" class="unity-concept__title">La scène : organiser un monde&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Une &lt;strong>scène&lt;/strong> est un asset qui enregistre un ensemble de GameObjects, leur organisation et leurs réglages. Elle peut représenter un niveau, une salle ou un écran de l’application. &lt;strong>Hierarchy&lt;/strong> montre les objets de la scène ouverte.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> &lt;code>UnityBasics&lt;/code> contient le sol, les cubes, la caméra et la lumière. Sauvegarder cette scène enregistre leur disposition. La fenêtre &lt;strong>Scene&lt;/strong> est une vue de travail sur ce monde ; la fenêtre &lt;strong>Game&lt;/strong> montre ce que rend la caméra.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-31">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-31" class="unity-concept__title">Le GameObject : un objet à composer&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Un &lt;strong>GameObject&lt;/strong> est le support de base d’un objet dans une scène. Son nom permet de le retrouver ; ses fonctionnalités viennent des composants qui lui sont attachés. Un GameObject peut être vide, sans géométrie visible.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> le cube, la caméra et la lumière sont tous des GameObjects. Ils ont des rôles différents parce qu’ils ne possèdent pas les mêmes composants.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-32">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-32" class="unity-concept__title">Les composants : donner des fonctions à un objet&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Un &lt;strong>composant&lt;/strong> ajoute une propriété ou un comportement à un GameObject. Unity fonctionne par &lt;strong>composition&lt;/strong> : vous assemblez plusieurs composants sur le même objet plutôt que de choisir un type d’objet unique qui ferait tout.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> un cube possède un Transform, un Mesh Filter, un Mesh Renderer et un Box Collider. Vous ajouterez un Rigidbody pour la physique, puis vos propres scripts. L’&lt;strong>Inspector&lt;/strong> montre ces composants ; &lt;strong>Add Component&lt;/strong> permet d’en ajouter.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-33">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-33" class="unity-concept__title">Le Transform : position, rotation et échelle&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Chaque GameObject possède un &lt;strong>Transform&lt;/strong>, qui définit sa &lt;strong>position&lt;/strong>, sa &lt;strong>rotation&lt;/strong> et son &lt;strong>échelle&lt;/strong>. Ces trois réglages servent à placer et orienter l’objet, et à modifier sa taille.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> le sol reste à l’origine &lt;code>(0, 0, 0)&lt;/code>. Vous modifiez le Transform des cubes pour construire les colonnes, puis un script fera varier leur rotation pendant l’exécution.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Outils de manipulation dans Unity 6.3" srcset="
/fr/teaching/lab/intro-unity/images/unity63-scene-tools_hu72bbc9834ff13589e627c63ba23c7732_5757_7bf8e4d9c102835589a63de493d930bf.webp 400w,
/fr/teaching/lab/intro-unity/images/unity63-scene-tools_hu72bbc9834ff13589e627c63ba23c7732_5757_4cb0329f4201f8d243a0349fda82a34f.webp 760w,
/fr/teaching/lab/intro-unity/images/unity63-scene-tools_hu72bbc9834ff13589e627c63ba23c7732_5757_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/unity63-scene-tools_hu72bbc9834ff13589e627c63ba23c7732_5757_7bf8e4d9c102835589a63de493d930bf.webp"
width="49"
height="211"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Sélectionnez un objet et appuyez sur &lt;strong>F&lt;/strong> dans Scene pour le cadrer. Utilisez Move, Rotate et Scale (&lt;strong>W&lt;/strong>, &lt;strong>E&lt;/strong>, &lt;strong>R&lt;/strong>, hors saisie de texte). Maintenez le bouton droit pour regarder autour de vous dans Scene ; les touches de déplacement permettent alors de naviguer. &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-34" popovertargetaction="show" aria-describedby="unity-term-34">Local/Global&lt;/button>&lt;span id="unity-term-34" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Local / Global&lt;/strong>&lt;span>Local utilise les axes propres à l’objet ; Global utilise les axes du monde. Les coordonnées d’un enfant peuvent aussi être exprimées relativement à son parent.&lt;/span>&lt;/span>
&lt;/strong> choisit le repère de manipulation. Consultez la &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/SceneViewNavigation.html" target="_blank" rel="noopener">navigation&lt;/a> et le &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/PositioningGameObjects.html" target="_blank" rel="noopener">positionnement&lt;/a>.&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-35">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-35" class="unity-concept__title">Edit et Play : construire, puis tester&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>&lt;strong>Edit&lt;/strong> sert à construire et configurer la scène ; &lt;strong>Play&lt;/strong> exécute l’application dans l’éditeur. Les changements des objets de la scène effectués en Play sont normalement annulés lorsque vous arrêtez l’exécution.&lt;/p>
&lt;p>&lt;strong>À essayer :&lt;/strong> lancez Play, déplacez un objet, puis arrêtez. Retrouvez sa position initiale. Arrêtez Play avant de régler définitivement la scène, puis sauvegardez. Cliquez dans Game avant de tester les entrées.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;h2 id="créer-une-scène-simple">Créer une scène simple&lt;/h2>
&lt;p>Nous allons créer un sol et une pile de douze cubes bleus.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Ajoutez &lt;strong>GameObject &amp;gt; 3D Object &amp;gt; Plane&lt;/strong>, nommé &lt;code>Ground&lt;/code>, en position &lt;code>(0, 0, 0)&lt;/code>, rotation &lt;code>(0, 0, 0)&lt;/code>, échelle &lt;code>(10, 1, 10)&lt;/code>. Le plan mesure 10 × 10 unités à l’échelle 1 : vous obtenez ici 100 × 100 unités. Une unité représente environ un mètre ; le plan reste fini.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Ajoutez un cube &lt;code>Cube&lt;/code>, d’échelle &lt;code>(1, 1, 1)&lt;/code>, en position &lt;code>(0, 3, 0)&lt;/code>.
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-36">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-36" class="unity-concept__title">Matériau, shader et texture : trois rôles différents&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Le &lt;strong>Mesh&lt;/strong> définit la géométrie. Le &lt;strong>Renderer&lt;/strong> l’affiche avec un ou plusieurs &lt;strong>matériaux&lt;/strong>. Un matériau est un asset : il choisit un &lt;strong>shader&lt;/strong> et lui fournit des paramètres, comme une couleur et des textures.&lt;/p>
&lt;p>Le shader calcule l’apparence de la surface ; une texture est une image utilisée dans ce calcul. Plusieurs matériaux peuvent utiliser la même texture, et plusieurs objets peuvent partager un matériau.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> &lt;code>CubeBlue&lt;/code> utilise le shader &lt;strong>URP Lit&lt;/strong> et une couleur bleue ; &lt;code>GroundGrid&lt;/code> utilise aussi une texture dans &lt;strong>Base Map&lt;/strong>. Le matériau doit employer un shader compatible avec le pipeline URP du projet.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Créez &lt;code>CubeBlue&lt;/code> dans &lt;code>Assets/Materials&lt;/code> (&lt;strong>Assets &amp;gt; Create &amp;gt; Material&lt;/strong>). Choisissez le &lt;button type="button" class="unity-term" popovertarget="unity-term-37" popovertargetaction="show" aria-describedby="unity-term-37">shader&lt;/button>&lt;span id="unity-term-37" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Shader&lt;/strong>&lt;span>Programme qui calcule l’apparence d’une surface. Le matériau choisit le shader et fournit ses paramètres et textures.&lt;/span>&lt;/span>
&lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-38" popovertargetaction="show" aria-describedby="unity-term-38">Universal Render Pipeline/Lit&lt;/button>&lt;span id="unity-term-38" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>URP Lit&lt;/strong>&lt;span>Shader standard d’URP qui calcule un matériau éclairé à partir de la couleur, des textures et des propriétés de surface.&lt;/span>&lt;/span>
&lt;/strong> et une couleur bleue dans &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-39" popovertargetaction="show" aria-describedby="unity-term-39">Base Map&lt;/button>&lt;span id="unity-term-39" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Base Map&lt;/strong>&lt;span>Texture et couleur de base d’un matériau URP Lit. Elles sont combinées pour déterminer sa couleur de surface.&lt;/span>&lt;/span>
&lt;/strong>. Glissez le matériau sur le cube.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Créez &lt;code>GroundGrid&lt;/code>, également en URP Lit, puis glissez &lt;code>grid_grey.png&lt;/code> dans sa &lt;strong>Base Map&lt;/strong>. Assignez ce matériau au plan. Cliquez sur la texture &lt;code>grid_grey.png&lt;/code> dans la fenêtre &lt;strong>Project&lt;/strong> : ses paramètres d’import apparaissent dans l’&lt;strong>Inspector&lt;/strong>. Vérifiez que &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-40" popovertargetaction="show" aria-describedby="unity-term-40">Wrap Mode&lt;/button>&lt;span id="unity-term-40" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Wrap Mode&lt;/strong>&lt;span>Réglage d’une texture qui détermine ce qui se passe hors de ses coordonnées normales. Repeat répète l’image.&lt;/span>&lt;/span>
= Repeat&lt;/strong> ; ce réglage est normalement déjà sélectionné. Si vous le modifiez, cliquez sur &lt;strong>Apply&lt;/strong>. Essayez un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-41" popovertargetaction="show" aria-describedby="unity-term-41">Tiling&lt;/button>&lt;span id="unity-term-41" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Tiling&lt;/strong>&lt;span>Paramètre de matériau qui règle combien de fois la texture se répète sur la surface.&lt;/span>&lt;/span>
= (100, 100)&lt;/strong> sur le matériau et ajustez-le. Un matériau décrit l’apparence ; une texture est une image utilisée par le matériau.
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-42">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-42" class="unity-concept__title">Le tag : identifier un objet dans les scripts&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Un &lt;strong>tag&lt;/strong> est une étiquette attribuée à un GameObject, distincte de son nom. Un script peut chercher un objet portant un tag précis. Chaque GameObject possède un tag ; plusieurs objets peuvent partager le même.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> le tag &lt;strong>MainCamera&lt;/strong> permettra à &lt;code>Camera.main&lt;/code> de retrouver la caméra active. Nommer un objet « Main Camera » ne suffit pas : vérifiez aussi son champ &lt;strong>Tag&lt;/strong> dans l’Inspector.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Placez la caméra, par exemple en position &lt;code>(8, 6, -12)&lt;/code> et rotation &lt;code>(20, -30, 0)&lt;/code>. Ajustez le cadrage dans Game pour voir le sol et le cube. Conservez le &lt;button type="button" class="unity-term" popovertarget="unity-term-43" popovertargetaction="show" aria-describedby="unity-term-43">tag&lt;/button>&lt;span id="unity-term-43" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Tag&lt;/strong>&lt;span>Étiquette attribuée à un GameObject pour l’identifier depuis les scripts. Par exemple, Camera.main trouve une caméra active portant MainCamera.&lt;/span>&lt;/span>
&lt;strong>MainCamera&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Exemple de cadrage" srcset="
/fr/teaching/lab/intro-unity/images/figure-04_hu0d1212bdc90c840bdc8a46a18fb2eaee_281261_2349f77e825b70c89e871ced2d48540e.webp 400w,
/fr/teaching/lab/intro-unity/images/figure-04_hu0d1212bdc90c840bdc8a46a18fb2eaee_281261_16e93c7c2a9fb4adf930190146ec9390.webp 760w,
/fr/teaching/lab/intro-unity/images/figure-04_hu0d1212bdc90c840bdc8a46a18fb2eaee_281261_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/figure-04_hu0d1212bdc90c840bdc8a46a18fb2eaee_281261_2349f77e825b70c89e871ced2d48540e.webp"
width="760"
height="359"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-44">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-44" class="unity-concept__title">Afficher, détecter les contacts et simuler le mouvement&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Ces trois fonctions sont séparées : le &lt;strong>Renderer&lt;/strong> affiche l’objet, le &lt;strong>Collider&lt;/strong> définit sa forme de collision et le &lt;strong>Rigidbody&lt;/strong> simule son mouvement sous l’effet de la gravité et des forces.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> le cube possède déjà un Box Collider, mais il faut ajouter un Rigidbody pour qu’il tombe. Le sol possède un collider et reste immobile sans Rigidbody. Un objet visible peut donc être traversé s’il n’a pas de collider.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;ol start="6">
&lt;li>
&lt;p>Ajoutez un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-45" popovertargetaction="show" aria-describedby="unity-term-45">Rigidbody&lt;/button>&lt;span id="unity-term-45" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Rigidbody&lt;/strong>&lt;span>Composant qui permet au moteur physique de simuler le mouvement d’un objet : gravité, forces et collisions.&lt;/span>&lt;/span>
&lt;/strong> au cube avec &lt;strong>Add Component&lt;/strong>. Gardez &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-46" popovertargetaction="show" aria-describedby="unity-term-46">Use Gravity&lt;/button>&lt;span id="unity-term-46" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Use Gravity&lt;/strong>&lt;span>Option d’un Rigidbody qui active l’effet de la gravité sur ce corps.&lt;/span>&lt;/span>
&lt;/strong> activé et &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-47" popovertargetaction="show" aria-describedby="unity-term-47">Is Kinematic&lt;/button>&lt;span id="unity-term-47" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Is Kinematic&lt;/strong>&lt;span>Quand cette option est active, le Rigidbody est piloté par le code ou l’animation plutôt que par les forces de la simulation.&lt;/span>&lt;/span>
&lt;/strong> désactivé. Le cube possède déjà un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-48" popovertargetaction="show" aria-describedby="unity-term-48">Box Collider&lt;/button>&lt;span id="unity-term-48" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Box Collider&lt;/strong>&lt;span>Collider en forme de boîte, simple et peu coûteux pour représenter un cube ou une partie d’objet.&lt;/span>&lt;/span>
&lt;/strong> ; le plan possède un &lt;button type="button" class="unity-term" popovertarget="unity-term-49" popovertargetaction="show" aria-describedby="unity-term-49">collider&lt;/button>&lt;span id="unity-term-49" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Collider&lt;/strong>&lt;span>Composant définissant une forme de collision. Il peut détecter les contacts sans afficher de géométrie.&lt;/span>&lt;/span>
. Lancez la scène : le cube tombe et reste sur le sol. Le &lt;button type="button" class="unity-term" popovertarget="unity-term-50" popovertargetaction="show" aria-describedby="unity-term-50">Renderer&lt;/button>&lt;span id="unity-term-50" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Renderer&lt;/strong>&lt;span>Composant qui affiche une géométrie et utilise ses matériaux pour déterminer son apparence.&lt;/span>&lt;/span>
affiche l’objet, le Collider définit sa forme de collision, le Rigidbody permet sa simulation physique.
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-51">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-51" class="unity-concept__title">Le prefab : réutiliser un objet et garder le lien&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Un &lt;strong>prefab&lt;/strong> est un asset qui enregistre un GameObject, ses composants et ses enfants. Chaque exemplaire placé dans la scène est une &lt;strong>instance&lt;/strong> liée au modèle. Ici, les douze cubes partageront &lt;code>CubePrefab&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Deux façons de modifier le modèle, hors Play :&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Depuis Project :&lt;/strong> sélectionnez &lt;code>CubePrefab&lt;/code> pour régler ses paramètres dans l’Inspector, ou double-cliquez dessus pour modifier sa structure en &lt;strong>Prefab Mode&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Depuis une instance :&lt;/strong> changez, par exemple, la &lt;strong>Mass&lt;/strong> d’un cube. Ce changement est un &lt;strong>override&lt;/strong> local. Dans &lt;strong>Overrides&lt;/strong>, en haut de l’Inspector, utilisez &lt;strong>Apply&lt;/strong> pour le reporter au modèle, ou &lt;strong>Apply All&lt;/strong> pour reporter toutes les modifications.&lt;/li>
&lt;/ul>
&lt;p>Les instances héritent des changements du modèle, sauf celles qui possèdent leur propre override sur la propriété concernée. &lt;strong>Revert&lt;/strong> annule un override pour retrouver la valeur du modèle. Déplacer un cube reste propre à cette instance.&lt;/p>
&lt;p>&lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/PrefabInstanceOverrides.html#apply-overrides-to-the-prefab-asset" target="_blank" rel="noopener">Appliquer ou annuler des overrides&lt;/a>.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Arrêtez Play. Glissez le cube de Hierarchy vers &lt;code>Assets/Prefabs&lt;/code> et nommez l’asset &lt;code>CubePrefab&lt;/code>. Créez au total &lt;strong>douze instances&lt;/strong>, disposées en &lt;strong>deux colonnes de six cubes qui se rapprochent vers le haut&lt;/strong>, comme sur l’image ci-dessous. Gardez une échelle &lt;code>(1, 1, 1)&lt;/code>, une rotation &lt;code>(0, 0, 0)&lt;/code> et Z &lt;code>0&lt;/code> pour tous les cubes.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Astuce — pour manipuler beaucoup d’objets :&lt;/strong> la &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/Hierarchy.html" target="_blank" rel="noopener">duplication avec Ctrl+D (Cmd+D sur macOS)&lt;/a>, la &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/SelectGameObjects.html" target="_blank" rel="noopener">sélection multiple&lt;/a> et les &lt;a href="https://docs.unity.com/en-us/engine/6000.3/manual/working-with-gameobjects/unity-components/inspector-manage-components/inspector-numeric-fields" target="_blank" rel="noopener">expressions numériques de l’Inspector, comme &lt;code>L(a,b)&lt;/code> pour répartir des objets régulièrement&lt;/a> peuvent faire gagner du temps. Pour les douze cubes de ce TP, placez simplement les instances pour reproduire la forme de l’image.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Deux colonnes de six cubes qui se rapprochent vers le haut" srcset="
/fr/teaching/lab/intro-unity/images/stack-inward-columns_hudef1ab08f8ec270ecf0a62b7e828224c_134793_afb75adc385d49c0c840ecedd474f840.webp 400w,
/fr/teaching/lab/intro-unity/images/stack-inward-columns_hudef1ab08f8ec270ecf0a62b7e828224c_134793_543e2d86f1bb74940a386f7308f84108.webp 760w,
/fr/teaching/lab/intro-unity/images/stack-inward-columns_hudef1ab08f8ec270ecf0a62b7e828224c_134793_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/stack-inward-columns_hudef1ab08f8ec270ecf0a62b7e828224c_134793_afb75adc385d49c0c840ecedd474f840.webp"
width="470"
height="508"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;ol start="8">
&lt;li>Testez la pile. Ouvrez &lt;code>CubePrefab&lt;/code> en double-cliquant et changez sa &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-52" popovertargetaction="show" aria-describedby="unity-term-52">Mass&lt;/button>&lt;span id="unity-term-52" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Mass&lt;/strong>&lt;span>Masse du Rigidbody. Elle influence la réponse aux forces et impulsions, sans rendre la chute libre plus rapide à elle seule.&lt;/span>&lt;/span>
&lt;/strong>, puis sa &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-53" popovertargetaction="show" aria-describedby="unity-term-53">Linear Damping&lt;/button>&lt;span id="unity-term-53" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Linear Damping&lt;/strong>&lt;span>Amortissement qui réduit progressivement la vitesse linéaire du Rigidbody. Il se distingue du frottement entre surfaces.&lt;/span>&lt;/span>
&lt;/strong>. &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-54" popovertargetaction="show" aria-describedby="unity-term-54">Angular Damping&lt;/button>&lt;span id="unity-term-54" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Angular Damping&lt;/strong>&lt;span>Amortissement qui réduit progressivement la vitesse de rotation du Rigidbody.&lt;/span>&lt;/span>
&lt;/strong> freine la rotation. Comparez les instances, puis remettez Mass à &lt;code>1&lt;/code> et Linear Damping à &lt;code>0&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>À observer :&lt;/strong> sans amortissement, une masse supérieure ne rend pas la chute plus rapide. Elle change la réponse à une même impulsion, que vous testerez ensuite. Le frottement au contact se règle avec un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-55" popovertargetaction="show" aria-describedby="unity-term-55">Physics Material&lt;/button>&lt;span id="unity-term-55" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Physics Material&lt;/strong>&lt;span>Asset qui règle le frottement et le rebond des colliders. Il ne définit pas la couleur visible de l’objet.&lt;/span>&lt;/span>
&lt;/strong> sur le Collider et se distingue de l’amortissement. Les valeurs modifiées seulement sur une instance peuvent être des &lt;em>&lt;button type="button" class="unity-term" popovertarget="unity-term-56" popovertargetaction="show" aria-describedby="unity-term-56">overrides&lt;/button>&lt;span id="unity-term-56" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Override de prefab&lt;/strong>&lt;span>Modification propre à une instance de prefab qui remplace un réglage hérité du modèle.&lt;/span>&lt;/span>
&lt;/em> : vérifiez-les si une modification du prefab ne se propage pas.&lt;/p>
&lt;h2 id="animer-un-objet-de-la-scène">Animer un objet de la scène&lt;/h2>
&lt;p>Un script C# dérivant de &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-57" popovertargetaction="show" aria-describedby="unity-term-57">MonoBehaviour&lt;/button>&lt;span id="unity-term-57" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>MonoBehaviour&lt;/strong>&lt;span>Classe de base des scripts attachables aux GameObjects. Unity appelle ses méthodes de cycle de vie, telles que Update.&lt;/span>&lt;/span>
&lt;/strong> devient un composant. Nous allons créer un script qui fait simplement tourner les cubes sur eux-mêmes.&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-58">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-58" class="unity-concept__title">Du fichier C# au composant Unity&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Un script est un &lt;strong>asset C# (&lt;code>.cs&lt;/code>) qui décrit un comportement&lt;/strong>. Dans ce TP, il contient une classe dérivée de &lt;strong>MonoBehaviour&lt;/strong>, de même nom que le fichier : &lt;code>RotateCube.cs&lt;/code> contient &lt;code>public class RotateCube : MonoBehaviour&lt;/code>.&lt;/p>
&lt;p>Enregistrez le fichier, puis revenez dans Unity : il &lt;strong>compile automatiquement&lt;/strong> le code. Corrigez les erreurs de &lt;strong>Console&lt;/strong> avant de continuer.&lt;/p>
&lt;p>Pour s’exécuter, le script doit être &lt;strong>ajouté à un GameObject comme composant&lt;/strong>, par glisser-déposer ou &lt;strong>Add Component&lt;/strong>. Chaque cube possède alors sa propre instance du composant et ses réglages. Ses &lt;strong>champs&lt;/strong> peuvent être exposés dans l’Inspector, comme vous allez le tester avec &lt;code>speed&lt;/code>.&lt;/p>
&lt;p>&lt;strong>&lt;code>transform&lt;/code>&lt;/strong> donne directement accès au Transform du GameObject qui porte le script : aucune référence à assigner pour faire tourner le cube.&lt;/p>
&lt;p>&lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/creating-scripts.html" target="_blank" rel="noopener">Créer un script&lt;/a> · &lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/SerializeField.html" target="_blank" rel="noopener">Exposer un champ avec SerializeField&lt;/a>.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-59">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-59" class="unity-concept__title">Start, Update et le cycle de vie d’un MonoBehaviour&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Unity appelle ces méthodes automatiquement : &lt;strong>pas de boucle à écrire ni d’appel à faire vous-même&lt;/strong>. Respectez leurs noms et signatures, par exemple &lt;code>void Start()&lt;/code> ; supprimez les méthodes vides inutiles.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>Start()&lt;/code> : préparer une fois&lt;/strong>, avant le premier Update du composant actif. Ici, vous y activerez les entrées ou mémoriserez la couleur initiale. Désactiver puis réactiver le composant ne relance pas Start.&lt;/li>
&lt;li>&lt;strong>&lt;code>Update()&lt;/code> : agir à chaque image&lt;/strong>, tant que le composant et son GameObject sont actifs. Vous y ferez tourner le cube avec &lt;strong>Time.deltaTime&lt;/strong> et y détecterez les tirs.&lt;/li>
&lt;/ul>
&lt;p>Pour les interactions souris, vous récupérerez directement le Renderer ou le Rigidbody avec &lt;strong>GetComponent dans la méthode qui en a besoin&lt;/strong>.&lt;/p>
&lt;details>
&lt;summary>Pour référence : les autres méthodes courantes&lt;/summary>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Méthode&lt;/th>
&lt;th>Quand intervient-elle ?&lt;/th>
&lt;th>Utilisation typique&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>Awake()&lt;/code>&lt;/td>
&lt;td>Une fois, à l’initialisation sur un GameObject actif, avant Start ; même si le composant est désactivé.&lt;/td>
&lt;td>Préparer ses références internes.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>OnEnable()&lt;/code>&lt;/td>
&lt;td>Chaque fois que le composant devient actif sur un GameObject actif.&lt;/td>
&lt;td>S’abonner aux événements.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>FixedUpdate()&lt;/code>&lt;/td>
&lt;td>Au rythme fixe de la simulation physique.&lt;/td>
&lt;td>Appliquer des forces continues à un Rigidbody.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>LateUpdate()&lt;/code>&lt;/td>
&lt;td>À chaque image, après les Update.&lt;/td>
&lt;td>Mettre à jour une caméra après le déplacement des objets.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>OnDisable()&lt;/code>&lt;/td>
&lt;td>Lorsque le composant ou son GameObject est désactivé.&lt;/td>
&lt;td>Retirer les abonnements aux événements.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>OnDestroy()&lt;/code>&lt;/td>
&lt;td>Lors de la destruction d’un objet précédemment actif.&lt;/td>
&lt;td>Libérer les ressources possédées par le composant.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Repère simplifié pour un composant actif :&lt;/strong> &lt;code>Awake → OnEnable → Start&lt;/code>, puis &lt;code>Update → LateUpdate&lt;/code> à chaque image. &lt;strong>FixedUpdate suit son propre rythme&lt;/strong> : il peut y avoir zéro, un ou plusieurs pas de physique par image. Ce repère ne fixe pas l’ordre des scripts entre différents GameObjects.&lt;/p>
&lt;/details>
&lt;p>&lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/execution-order.html" target="_blank" rel="noopener">Cycle de vie et ordre d’exécution&lt;/a> · &lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/MonoBehaviour.html" target="_blank" rel="noopener">Méthodes de MonoBehaviour&lt;/a>.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;h3 id="écrire-rotatecube">Écrire RotateCube&lt;/h3>
&lt;ol>
&lt;li>Dans &lt;code>Assets/Scripts&lt;/code>, créez &lt;strong>Assets &amp;gt; Create &amp;gt; Scripting &amp;gt; MonoBehaviour Script&lt;/strong>, nommé &lt;code>RotateCube&lt;/code>. Ouvrez-le dans votre éditeur C# ; le nom de classe doit correspondre au fichier.&lt;/li>
&lt;/ol>
&lt;aside class="unity-concept unity-concept--advice" role="note" aria-labelledby="unity-concept-60">
&lt;p class="unity-concept__label">Vérification indispensable&lt;/p>
&lt;h4 id="unity-concept-60" class="unity-concept__title">Avant de coder : vérifier l’autocomplétion&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Attendez que l’éditeur C# ait chargé le projet. Dans le corps de &lt;code>Update()&lt;/code>, faites ces essais temporaires, un par un :&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Saisissez&lt;/th>
&lt;th>Suggestion attendue&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>transform.&lt;/code>&lt;/td>
&lt;td>&lt;code>Rotate&lt;/code>, &lt;code>position&lt;/code>…&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Vector3.&lt;/code>&lt;/td>
&lt;td>&lt;code>up&lt;/code>, &lt;code>forward&lt;/code>…&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Time.&lt;/code>&lt;/td>
&lt;td>&lt;code>deltaTime&lt;/code>…&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>La liste doit proposer des &lt;strong>membres de l’API Unity&lt;/strong>, pas seulement des mots déjà présents dans le fichier. Si elle ne s’ouvre pas automatiquement, essayez &lt;strong>Ctrl+Espace&lt;/strong>. Effacez les essais avant d’enregistrer.&lt;/p>
&lt;p>&lt;strong>Ne poursuivez pas tant que ces suggestions ne fonctionnent pas.&lt;/strong> Dans Unity, vérifiez &lt;strong>Edit &amp;gt; Preferences &amp;gt; External Tools &amp;gt; External Script Editor&lt;/strong>, puis rouvrez le script depuis &lt;strong>Project&lt;/strong>. Avec VS Code, vérifiez que l’extension &lt;strong>Unity de Microsoft&lt;/strong> et ses dépendances C# sont actives. Consultez le &lt;a href="../../tutorial/unity-instructions-pc-ecole/#visual-studio-code-%c3%a9diteur-c">guide de configuration&lt;/a> ou demandez de l’aide à l’enseignant.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;ol start="2">
&lt;li>Déclarez &lt;strong>&lt;code>speed&lt;/code> comme un attribut de la classe &lt;code>RotateCube&lt;/code>&lt;/strong> (appelé &lt;em>champ&lt;/em> en C#). Placez cette déclaration &lt;strong>dans les accolades de la classe, mais en dehors des méthodes&lt;/strong> comme &lt;code>Start()&lt;/code> et &lt;code>Update()&lt;/code>. Ce champ stocke la vitesse de rotation du composant ; ce n’est pas une variable locale à une méthode. L’annotation &lt;button type="button" class="unity-term" popovertarget="unity-term-61" popovertargetaction="show" aria-describedby="unity-term-61">SerializeField&lt;/button>&lt;span id="unity-term-61" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>SerializeField&lt;/strong>&lt;span>Attribut C# qui permet à Unity d’enregistrer un champ privé et de l’afficher dans l’Inspector.&lt;/span>&lt;/span>
permet de l’exposer dans l’Inspector.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[SerializeField]&lt;/span> &lt;span class="k">private&lt;/span> &lt;span class="kt">float&lt;/span> &lt;span class="n">speed&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">90f&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// degrés par seconde&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="3">
&lt;li>Dans &lt;button type="button" class="unity-term" popovertarget="unity-term-62" popovertargetaction="show" aria-describedby="unity-term-62">Update()&lt;/button>&lt;span id="unity-term-62" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Update&lt;/strong>&lt;span>Méthode d’un MonoBehaviour appelée une fois par image lorsque le composant est actif.&lt;/span>&lt;/span>
, appelé une fois par image, utilisez :&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">transform&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Rotate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Vector3&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">up&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">speed&lt;/span> &lt;span class="p">*&lt;/span> &lt;span class="n">Time&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">deltaTime&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Space&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Self&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;button type="button" class="unity-term" popovertarget="unity-term-63" popovertargetaction="show" aria-describedby="unity-term-63">Time.deltaTime&lt;/button>&lt;span id="unity-term-63" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Time.deltaTime&lt;/strong>&lt;span>Durée de l’image précédente, en secondes. Multiplier une vitesse par cette durée donne le déplacement ou la rotation pour l’image courante.&lt;/span>&lt;/span>
est le temps écoulé depuis l’image précédente : la vitesse ne dépend ainsi pas du nombre d’images par seconde. Une rotation de 3° par image donnerait des vitesses différentes selon la machine.&lt;/p>
&lt;ol start="4">
&lt;li>&lt;strong>Testez sur un seul cube.&lt;/strong> Sélectionnez une instance dans &lt;strong>Hierarchy&lt;/strong>. Glissez &lt;code>RotateCube.cs&lt;/code> depuis &lt;strong>Project&lt;/strong> sur ce cube ou dans son Inspector ; vous pouvez aussi cliquer sur &lt;strong>Add Component&lt;/strong>, rechercher &lt;strong>RotateCube&lt;/strong> et le sélectionner. Vérifiez que le composant apparaît dans l’Inspector. Lancez Play : seul ce cube tourne, car &lt;code>transform&lt;/code> désigne le GameObject auquel le script est attaché.&lt;/li>
&lt;li>&lt;strong>Étendez le comportement aux autres cubes.&lt;/strong> Arrêtez Play. L’ajout du composant sur cette instance est un &lt;strong>override&lt;/strong>. Dans &lt;strong>Overrides&lt;/strong>, en haut de son Inspector, sélectionnez l’ajout de &lt;strong>RotateCube&lt;/strong> et appliquez-le au prefab avec &lt;strong>Apply&lt;/strong>. Le modèle &lt;code>CubePrefab&lt;/code> possède maintenant ce composant, et les autres instances en héritent. Lancez Play pour observer la rotation de tous les cubes.&lt;/li>
&lt;li>&lt;strong>Autre méthode : modifier directement le modèle.&lt;/strong> Vous pouvez aussi ouvrir &lt;code>CubePrefab&lt;/code> depuis &lt;strong>Project&lt;/strong> et lui ajouter RotateCube avec le même glisser-déposer ou &lt;strong>Add Component&lt;/strong>. Pour faire tourner seulement quelques cubes, ajoutez plutôt le script aux instances choisies sans appliquer cet ajout au prefab. &lt;strong>Ajoutez-le une seule fois par cube&lt;/strong>, pour éviter que deux composants RotateCube cumulent leurs rotations.&lt;/li>
&lt;li>Testez plusieurs vitesses dans l’Inspector. Puis, hors Play, remplacez temporairement la déclaration par &lt;code>public float speed = 90f;&lt;/code>, puis par &lt;code>private float speed = 90f;&lt;/code>. Enregistrez et laissez Unity compiler à chaque fois : &lt;strong>Speed apparaît-il encore dans l’Inspector ?&lt;/strong> Terminez en remettant &lt;code>[SerializeField] private float speed = 90f;&lt;/code>.&lt;/li>
&lt;/ol>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-64">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-64" class="unity-concept__title">À retenir : public, private et SerializeField&lt;/h4>
&lt;div class="unity-concept__body">&lt;ul>
&lt;li>&lt;strong>&lt;code>public&lt;/code>&lt;/strong> : accessible aux autres scripts et visible dans l’Inspector pour un type pris en charge.&lt;/li>
&lt;li>&lt;strong>&lt;code>private&lt;/code>&lt;/strong> : réservé à la classe, masqué dans l’Inspector.&lt;/li>
&lt;li>&lt;strong>&lt;code>[SerializeField] private&lt;/code>&lt;/strong> : privé dans le code, mais enregistré par Unity et réglable dans l’Inspector. &lt;strong>C’est le choix conseillé ici.&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Encapsulation :&lt;/strong> gardez les champs privés et exposez seulement les réglages utiles. Pour les échanges entre scripts, préférez une propriété en lecture seule ou une méthode qui contrôle la modification. L’Inspector peut toujours recevoir une valeur incohérente.&lt;/p>
&lt;p>La valeur enregistrée dans l’Inspector prime sur la valeur initiale du code. Choisissez &lt;strong>instance ou prefab&lt;/strong> selon la portée souhaitée. Pour garder un réglage essayé en Play, remettez-le en mode édition et sauvegardez.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;p>&lt;strong>Vérification :&lt;/strong> les cubes tournent sur eux-mêmes et la vitesse se règle dans l’Inspector sans éditer le script.&lt;/p>
&lt;h2 id="gestion-des-interactions">Gestion des interactions&lt;/h2>
&lt;p>&lt;strong>Complétez &lt;code>Assets/Scripts/RotateCube.cs&lt;/code>&lt;/strong> pour que le cube soit immobile au démarrage et que chaque appui sur &lt;strong>R&lt;/strong> démarre ou arrête sa rotation.&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-65">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-65" class="unity-concept__title">Une action et son binding&lt;/h4>
&lt;div class="unity-concept__body">Une &lt;strong>InputAction&lt;/strong> décrit une intention, ici &lt;code>ActivateRotation&lt;/code>. Son &lt;strong>binding&lt;/strong> la relie à un contrôle, ici la touche R. L’événement &lt;strong>performed&lt;/strong> prévient votre script lorsque l’action est déclenchée.&lt;/div>
&lt;/aside>
&lt;ol>
&lt;li>&lt;strong>Importer l’Input System.&lt;/strong> Ajoutez &lt;code>using UnityEngine.InputSystem;&lt;/code> en haut du fichier, en conservant &lt;code>using UnityEngine;&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Déclarer l’action.&lt;/strong> Dans la classe, à côté de &lt;code>speed&lt;/code> et en dehors des méthodes, ajoutez un champ privé &lt;strong>&lt;code>activateRotation&lt;/code>&lt;/strong> de type &lt;button type="button" class="unity-term" popovertarget="unity-term-66" popovertargetaction="show" aria-describedby="unity-term-66">InputAction&lt;/button>&lt;span id="unity-term-66" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Input Action&lt;/strong>&lt;span>Action logique, comme sauter ou tourner, liée à des contrôles d’entrée. Elle peut être lue ou déclencher des callbacks.&lt;/span>&lt;/span>
, exposé avec &lt;code>[SerializeField]&lt;/code>. Initialisez-le avec &lt;code>new InputAction(...)&lt;/code> et ces trois arguments, dans cet ordre : le nom &lt;code>&amp;quot;ActivateRotation&amp;quot;&lt;/code>, le type &lt;code>InputActionType.Button&lt;/code> et le &lt;button type="button" class="unity-term" popovertarget="unity-term-67" popovertargetaction="show" aria-describedby="unity-term-67">binding&lt;/button>&lt;span id="unity-term-67" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Binding&lt;/strong>&lt;span>Association entre une action et un contrôle, par exemple la touche R ou le bouton droit de la souris.&lt;/span>&lt;/span>
&lt;code>&amp;quot;&amp;lt;Keyboard&amp;gt;/r&amp;quot;&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Mémoriser l’état de la rotation.&lt;/strong> Ajoutez un champ privé &lt;strong>&lt;code>rotating&lt;/code>&lt;/strong> de type &lt;code>bool&lt;/code>, initialisé à &lt;code>false&lt;/code>. Il indique si le cube doit tourner ; il n’a pas besoin d’être exposé dans l’Inspector. Conservez le champ &lt;code>speed&lt;/code> déjà créé.&lt;/li>
&lt;li>&lt;strong>Écrire la méthode de basculement.&lt;/strong> Ajoutez une méthode privée &lt;strong>&lt;code>ToggleRotation&lt;/code>&lt;/strong>, qui retourne &lt;code>void&lt;/code> et reçoit un paramètre &lt;code>InputAction.CallbackContext context&lt;/code>. Dans son corps, affectez à &lt;code>rotating&lt;/code> l’inverse de sa valeur actuelle avec l’opérateur &lt;strong>&lt;code>!&lt;/code>&lt;/strong> : &lt;code>false&lt;/code> devient &lt;code>true&lt;/code>, et inversement. Le paramètre &lt;code>context&lt;/code> est fourni par l’Input System ; vous n’avez pas à l’utiliser ici.&lt;/li>
&lt;li>&lt;strong>Faire l’abonnement dans &lt;code>Start()&lt;/code>.&lt;/strong> Abonnez &lt;code>ToggleRotation&lt;/code> à l’événement &lt;strong>&lt;code>performed&lt;/code>&lt;/strong> de &lt;code>activateRotation&lt;/code> avec &lt;strong>&lt;code>+=&lt;/code>&lt;/strong>, en écrivant le nom de la méthode sans parenthèses. Cet abonnement indique quelle méthode appeler lorsque l’action se déclenche.&lt;/li>
&lt;/ol>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-68">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-68" class="unity-concept__title">S’abonner à un événement avec &amp;#43;=&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Avec un événement C#, &lt;strong>&lt;code>+=&lt;/code> ajoute une méthode à appeler lorsque cet événement se produit&lt;/strong> : c’est un &lt;em>abonnement&lt;/em>. On fournit le nom de la méthode sans parenthèses pour qu’elle soit appelée plus tard. &lt;strong>&lt;code>-=&lt;/code>&lt;/strong> permet de retirer cet abonnement.&lt;/p>
&lt;p>Une InputAction propose trois événements :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>started&lt;/code>&lt;/strong> : l’interaction commence.&lt;/li>
&lt;li>&lt;strong>&lt;code>performed&lt;/code>&lt;/strong> : l’action est déclenchée selon sa configuration.&lt;/li>
&lt;li>&lt;strong>&lt;code>canceled&lt;/code>&lt;/strong> : l’action est annulée ou revient au repos.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Pour notre bouton R, abonnez uniquement &lt;code>performed&lt;/code> à &lt;code>ToggleRotation&lt;/code>&lt;/strong> : avec le comportement d’appui par défaut, la méthode est appelée à l’appui, sans basculer de nouveau au relâchement.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;ol start="6">
&lt;li>&lt;strong>Activer l’action dans &lt;code>Start()&lt;/code>.&lt;/strong> Après l’abonnement, appelez &lt;strong>&lt;code>Enable()&lt;/code> sur &lt;code>activateRotation&lt;/code>&lt;/strong>. Cette seconde instruction permet à l’action de recevoir les entrées : &lt;strong>l’abonnement seul ne suffit pas&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Conditionner la rotation dans &lt;code>Update()&lt;/code>.&lt;/strong> Gardez l’instruction &lt;code>transform.Rotate(...)&lt;/code> de l’exercice précédent, mais placez-la dans un &lt;strong>&lt;code>if&lt;/code>&lt;/strong> qui vérifie &lt;code>rotating&lt;/code>. Le cube tourne alors uniquement lorsque ce booléen vaut &lt;code>true&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Vérifier dans Unity.&lt;/strong> Enregistrez, attendez la compilation et inspectez le composant &lt;strong>RotateCube&lt;/strong> : l’action doit être de type &lt;strong>Button&lt;/strong>, liée à R. Ces réglages sont les valeurs initiales proposées par le code. Comme pour &lt;strong>Speed&lt;/strong>, vous pouvez les modifier dans l’Inspector ; sur une instance de prefab, cela crée un &lt;strong>override&lt;/strong>. Pour ce test, gardez R et le comportement d’appui par défaut.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Vérification :&lt;/strong> cliquez dans Game après avoir lancé Play. Les cubes sont immobiles au départ ; un appui sur R les fait tourner, relâcher R ne change rien, et un nouvel appui les arrête.&lt;/p>
&lt;aside class="unity-concept unity-concept--try" role="note" aria-labelledby="unity-concept-69">
&lt;p class="unity-concept__label">À essayer&lt;/p>
&lt;h4 id="unity-concept-69" class="unity-concept__title">Variation optionnelle : maintenir R pour tourner&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Adaptez le script pour que les cubes tournent &lt;strong>uniquement pendant que R est maintenue&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>Remplacez le basculement dans &lt;code>ToggleRotation&lt;/code> par une affectation de &lt;code>rotating&lt;/code> à &lt;code>true&lt;/code>. Vous pouvez renommer cette méthode &lt;code>StartRotation&lt;/code> et mettre à jour son abonnement à &lt;strong>performed&lt;/strong> dans &lt;code>Start()&lt;/code>.&lt;/li>
&lt;li>Créez une seconde méthode, &lt;code>StopRotation&lt;/code>, avec le même type de paramètre &lt;code>InputAction.CallbackContext context&lt;/code>, qui affecte &lt;code>false&lt;/code> à &lt;code>rotating&lt;/code>.&lt;/li>
&lt;li>Dans &lt;code>Start()&lt;/code>, abonnez cette seconde méthode à &lt;strong>canceled&lt;/strong> avec &lt;code>+=&lt;/code>. Avec notre configuration par défaut, cet événement est émis au relâchement de R. Gardez l’appel à &lt;code>Enable()&lt;/code> et la condition dans &lt;code>Update()&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Test :&lt;/strong> maintenez R : les cubes tournent. Relâchez R : ils s’arrêtent. Appuyez de nouveau pour recommencer.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;p>&lt;a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.20/manual/Actions.html" target="_blank" rel="noopener">Documentation des actions&lt;/a>.&lt;/p>
&lt;h2 id="programmation-dinteraction-simple-avec-la-souris">Programmation d’interaction simple avec la souris&lt;/h2>
&lt;p>Nous allons rendre chaque cube &lt;strong>rouge lorsque la souris le survole&lt;/strong>, lui rendre sa couleur initiale lorsque la souris s’en éloigne et &lt;strong>le pousser au clic gauche&lt;/strong>.&lt;/p>
&lt;p>Pour détecter ces interactions, nous allons ajouter un &lt;strong>EventSystem&lt;/strong> à la scène et un &lt;strong>Physics Raycaster&lt;/strong> à la caméra. Le premier transmet les événements de la souris ; le second détermine quel objet est sous le pointeur en utilisant ses colliders. Notre script &lt;code>MouseInteraction&lt;/code> recevra alors ces événements dans trois méthodes : &lt;strong>&lt;code>OnPointerEnter&lt;/code>&lt;/strong> pour le début du survol, &lt;strong>&lt;code>OnPointerExit&lt;/code>&lt;/strong> pour sa fin et &lt;strong>&lt;code>OnPointerClick&lt;/code>&lt;/strong> pour le clic.&lt;/p>
&lt;ol>
&lt;li>Ajoutez &lt;strong>GameObject &amp;gt; UI &amp;gt; Event System&lt;/strong> si la scène n’en possède pas. Gardez &lt;strong>un seul EventSystem actif&lt;/strong>. Son module doit être &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-70" popovertargetaction="show" aria-describedby="unity-term-70">Input System UI Input Module&lt;/button>&lt;span id="unity-term-70" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Input System UI Input Module&lt;/strong>&lt;span>Module qui traduit les actions de l’Input System en événements distribués par l’EventSystem.&lt;/span>&lt;/span>
&lt;/strong> : remplacez &lt;strong>Standalone Input Module&lt;/strong> si présent. Utilisez &lt;strong>Assign Default Actions&lt;/strong> si les références d’actions UI sont vides.&lt;/li>
&lt;li>Ajoutez &lt;strong>Physics Raycaster&lt;/strong> via Add Component sur la caméra active portant le tag &lt;strong>MainCamera&lt;/strong>. Les cubes doivent avoir leurs colliders et appartenir à un &lt;button type="button" class="unity-term" popovertarget="unity-term-71" popovertargetaction="show" aria-describedby="unity-term-71">layer&lt;/button>&lt;span id="unity-term-71" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Layer&lt;/strong>&lt;span>Catégorie attribuée aux GameObjects pour filtrer notamment le rendu, les collisions et les raycasts. Un masque sélectionne plusieurs layers.&lt;/span>&lt;/span>
inclus dans le masque du raycaster.&lt;/li>
&lt;li>Créez un &lt;strong>nouveau script &lt;code>MouseInteraction.cs&lt;/code>&lt;/strong> dans &lt;code>Assets/Scripts&lt;/code> et complétez-le dans les étapes suivantes. Importez &lt;code>UnityEngine.EventSystems&lt;/code> et implémentez les trois interfaces &lt;code>IPointerClickHandler&lt;/code>, &lt;code>IPointerEnterHandler&lt;/code> et &lt;code>IPointerExitHandler&lt;/code>. Les méthodes à définir sont &lt;code>OnPointerClick&lt;/code>, &lt;code>OnPointerEnter&lt;/code> et &lt;code>OnPointerExit&lt;/code>, chacune publique, retournant &lt;code>void&lt;/code> et recevant &lt;code>PointerEventData eventData&lt;/code>.&lt;/li>
&lt;/ol>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-72">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-72" class="unity-concept__title">Rappel : une interface est un contrat&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Une &lt;strong>interface C#&lt;/strong> décrit des méthodes qu’une classe doit fournir, avec leurs noms, paramètres et types de retour. La classe qui l’implémente écrit le comportement de ces méthodes ; elle peut implémenter plusieurs interfaces.&lt;/p>
&lt;p>&lt;strong>Syntaxe :&lt;/strong> après &lt;code>:&lt;/code>, indiquez la classe de base, puis les interfaces séparées par des virgules :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">MouseInteraction&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">MonoBehaviour&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">IPointerClickHandler&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">IPointerEnterHandler&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">IPointerExitHandler&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dans les accolades de cette classe, définissez ensuite les méthodes demandées par les interfaces.&lt;/p>
&lt;p>&lt;strong>Ici :&lt;/strong> &lt;code>IPointerClickHandler&lt;/code> demande une méthode &lt;code>OnPointerClick&lt;/code>. L’EventSystem reconnaît cette interface et appelle cette méthode lors d’un clic. Vous décidez ce que fait le cube dans son corps. Les deux autres interfaces suivent le même principe pour le début et la fin du survol.&lt;/p>
&lt;p>&lt;a href="https://learn.microsoft.com/fr-fr/dotnet/csharp/fundamentals/types/interfaces" target="_blank" rel="noopener">En savoir plus sur les interfaces C# — Microsoft Learn&lt;/a>.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;ol start="4">
&lt;li>&lt;strong>Préparer le composant.&lt;/strong> Laissez d’abord les trois méthodes d’interaction vides, enregistrez et vérifiez que le script compile. Ajoutez &lt;strong>MouseInteraction&lt;/strong> à &lt;code>CubePrefab&lt;/code> pour que chaque cube possède ce comportement. Toutes les modifications ci-dessous se font dans &lt;strong>&lt;code>MouseInteraction.cs&lt;/code>&lt;/strong>. Vous n’avez rien à mettre dans &lt;code>Update()&lt;/code> : les méthodes d’interaction seront appelées lors des événements de souris.&lt;/li>
&lt;li>&lt;strong>Mémoriser la couleur de départ.&lt;/strong> Déclarez un champ privé &lt;strong>&lt;code>initialColor&lt;/code>&lt;/strong>, de type &lt;code>Color&lt;/code>, dans la classe, en dehors des méthodes. Dans &lt;strong>&lt;code>Start()&lt;/code>&lt;/strong>, récupérez le Renderer du cube avec &lt;code>gameObject.&lt;/code> suivi de &lt;button type="button" class="unity-term" popovertarget="unity-term-73" popovertargetaction="show" aria-describedby="unity-term-73">GetComponent&lt;/button>&lt;span id="unity-term-73" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>GetComponent&lt;/strong>&lt;span>Méthode qui cherche un composant du type demandé sur le même GameObject. GetComponentInChildren cherche aussi dans ses enfants.&lt;/span>&lt;/span>
&lt;code>&amp;lt;Renderer&amp;gt;()&lt;/code>. Accédez ensuite à sa propriété &lt;strong>&lt;code>material.color&lt;/code>&lt;/strong> et enregistrez cette couleur dans &lt;code>initialColor&lt;/code>. Chaque cube mémorise ainsi sa propre couleur au démarrage.&lt;/li>
&lt;li>&lt;strong>Rendre le cube rouge au survol.&lt;/strong> Dans &lt;strong>&lt;code>OnPointerEnter&lt;/code>&lt;/strong>, récupérez le Renderer de la même façon et affectez &lt;strong>&lt;code>Color.red&lt;/code>&lt;/strong> à sa propriété &lt;code>material.color&lt;/code>. &lt;strong>Test :&lt;/strong> enregistrez, lancez Play et passez la souris sur un cube dans Game : seul ce cube doit devenir rouge.&lt;/li>
&lt;li>&lt;strong>Restaurer la couleur à la sortie.&lt;/strong> Dans &lt;strong>&lt;code>OnPointerExit&lt;/code>&lt;/strong>, affectez cette fois &lt;strong>&lt;code>initialColor&lt;/code>&lt;/strong> à la même propriété &lt;code>material.color&lt;/code>. &lt;strong>Test :&lt;/strong> éloignez la souris du cube : il doit retrouver sa couleur de départ. Utilisez bien &lt;code>material&lt;/code>, qui permet de modifier l’apparence de ce cube individuellement.&lt;/li>
&lt;li>&lt;strong>Pousser le cube au clic gauche.&lt;/strong> Dans &lt;strong>&lt;code>OnPointerClick&lt;/code>&lt;/strong>, ajoutez un &lt;strong>&lt;code>if&lt;/code>&lt;/strong> qui compare &lt;code>eventData.button&lt;/code> à &lt;strong>&lt;code>PointerEventData.InputButton.Left&lt;/code>&lt;/strong>. À l’intérieur, récupérez le &lt;strong>Rigidbody&lt;/strong> avec &lt;code>gameObject.GetComponent&amp;lt;Rigidbody&amp;gt;()&lt;/code>, puis appelez sa méthode &lt;strong>&lt;code>AddForce&lt;/code>&lt;/strong> avec deux arguments : la direction &lt;button type="button" class="unity-term" popovertarget="unity-term-74" popovertargetaction="show" aria-describedby="unity-term-74">Camera.main&lt;/button>&lt;span id="unity-term-74" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Camera.main&lt;/strong>&lt;span>Référence obtenue vers une caméra active portant le tag MainCamera. Ce n’est pas le Transform cible de Cinemachine.&lt;/span>&lt;/span>
&lt;code>.transform.forward&lt;/code> multipliée par &lt;strong>&lt;code>5f&lt;/code>&lt;/strong>, et le mode &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-75" popovertargetaction="show" aria-describedby="unity-term-75">ForceMode.Impulse&lt;/button>&lt;span id="unity-term-75" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>ForceMode.Impulse&lt;/strong>&lt;span>Mode d’application d’une poussée instantanée au Rigidbody, dont l’effet dépend de sa masse.&lt;/span>&lt;/span>
&lt;/strong> pour une poussée ponctuelle. &lt;strong>Test :&lt;/strong> le clic gauche pousse le cube dans la direction du regard de la caméra ; le clic droit ne le pousse pas.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Vérification :&lt;/strong> seul le cube survolé devient rouge ; le clic gauche le pousse, le clic droit ne le pousse pas. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/MonoBehaviour.html" target="_blank" rel="noopener">MonoBehaviour et son cycle de vie&lt;/a>.&lt;/p>
&lt;aside class="unity-concept unity-concept--try" role="note" aria-labelledby="unity-concept-76">
&lt;p class="unity-concept__label">À essayer&lt;/p>
&lt;h4 id="unity-concept-76" class="unity-concept__title">Pour aller plus loin : une force pendant l’appui&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Notre script applique une &lt;strong>impulsion une seule fois par clic&lt;/strong> : il donne une poussée ponctuelle au cube. Imaginez maintenant une force appliquée &lt;strong>tant que le bouton gauche reste enfoncé&lt;/strong>.&lt;/p>
&lt;p>Pour adapter le script, mémorisez l’appui dans un booléen : &lt;code>IPointerDownHandler&lt;/code> et sa méthode &lt;code>OnPointerDown&lt;/code> permettent de commencer la poussée, tandis que &lt;code>IPointerUpHandler&lt;/code> et &lt;code>OnPointerUp&lt;/code> permettent de l’arrêter au relâchement. Dans &lt;strong>&lt;code>FixedUpdate()&lt;/code>&lt;/strong>, si ce booléen est vrai, appelez &lt;code>AddForce&lt;/code> avec &lt;strong>&lt;code>ForceMode.Force&lt;/code>&lt;/strong>. La force est alors appliquée à chaque pas de simulation physique, plutôt qu’une seule fois dans &lt;code>OnPointerClick&lt;/code> ; retirez l’ancienne impulsion pour ne pas cumuler les deux.&lt;/p>
&lt;p>&lt;strong>À comparer :&lt;/strong> un appui bref et un appui prolongé. Comment changent le mouvement du cube et l’effet de sa masse ?&lt;/p>
&lt;/div>
&lt;/aside>
&lt;h2 id="navigation-en-réutilisant-des-scripts-dinteraction-claviersouris">Navigation en réutilisant des scripts d’interaction clavier/souris&lt;/h2>
&lt;p>Intégrez un contrôleur première personne à votre scène avec le package officiel &lt;strong>&lt;a href="https://assetstore.unity.com/packages/3d/characters/first-person-third-person-character-controllers-196526" target="_blank" rel="noopener">First Person + Third Person | Character Controllers&lt;/a>&lt;/strong>. Il fournit les scripts nécessaires pour déplacer le personnage au clavier et regarder autour de lui avec la souris.&lt;/p>
&lt;ol>
&lt;li>Après l’import via &lt;strong>Package Manager &amp;gt; My Assets&lt;/strong>, ouvrez dans Project &lt;strong>&lt;code>Assets/Starter Assets/Sample/FirstPersonController/Playground.unity&lt;/code>&lt;/strong>, la scène de démonstration première personne, et testez-la. Relevez les bindings de déplacement, saut, sprint et regard dans l’Input Actions asset : les touches dépendent de sa configuration et du clavier.&lt;/li>
&lt;li>Identifiez le &lt;strong>personnage avec &lt;button type="button" class="unity-term" popovertarget="unity-term-77" popovertargetaction="show" aria-describedby="unity-term-77">CharacterController&lt;/button>&lt;span id="unity-term-77" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>CharacterController&lt;/strong>&lt;span>Composant de déplacement de personnage avec une forme de capsule et une gestion des collisions, piloté par un script plutôt que par les forces d’un Rigidbody.&lt;/span>&lt;/span>
&lt;/strong>, la &lt;strong>caméra de rendu avec Camera / &lt;button type="button" class="unity-term" popovertarget="unity-term-78" popovertargetaction="show" aria-describedby="unity-term-78">AudioListener&lt;/button>&lt;span id="unity-term-78" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>AudioListener&lt;/strong>&lt;span>Composant représentant le point d’écoute du son dans la scène, généralement placé sur la caméra active.&lt;/span>&lt;/span>
/ &lt;button type="button" class="unity-term" popovertarget="unity-term-79" popovertargetaction="show" aria-describedby="unity-term-79">Cinemachine Brain&lt;/button>&lt;span id="unity-term-79" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Cinemachine&lt;/strong>&lt;span>Package qui pilote des caméras : suivi d’une cible, cadrage et transitions. La caméra Unity conserve le rôle de produire l’image.&lt;/span>&lt;/span>
&lt;/strong>, et la &lt;strong>Cinemachine Camera&lt;/strong> pilotant le suivi. La cible de suivi (par exemple &lt;code>PlayerCameraRoot&lt;/code>) est un Transform ; &lt;strong>ce n’est pas nécessairement la caméra de rendu&lt;/strong>.&lt;/li>
&lt;li>Dans &lt;strong>Hierarchy&lt;/strong>, sélectionnez ensemble &lt;strong>MainCamera&lt;/strong>, &lt;strong>PlayerFollowCamera&lt;/strong>, &lt;strong>PlayerCapsule&lt;/strong>, &lt;strong>UI_EventSystem&lt;/strong> et &lt;strong>UI_TouchScreenInput&lt;/strong>, encadrés sur la capture ci-dessous, puis copiez-les. Ouvrez &lt;strong>&lt;code>UnityBasics&lt;/code>, la scène du TP&lt;/strong>, puis collez-les. Copiez ces objets ensemble pour conserver les références du &lt;button type="button" class="unity-term" popovertarget="unity-term-80" popovertargetaction="show" aria-describedby="unity-term-80">rig&lt;/button>&lt;span id="unity-term-80" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Rig de caméra/personnage&lt;/strong>&lt;span>Ensemble d’objets et de composants reliés qui assurent le déplacement du personnage et le suivi de caméra.&lt;/span>&lt;/span>
première personne.&lt;/li>
&lt;/ol>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Éléments à copier depuis la scène de démonstration" srcset="
/fr/teaching/lab/intro-unity/images/first-person-objects-to-copy_hu8b0e4f3b2126b182dfe7c755e69b6d40_1395374_46697a23d5bb07de57e7a7d109430a7f.webp 400w,
/fr/teaching/lab/intro-unity/images/first-person-objects-to-copy_hu8b0e4f3b2126b182dfe7c755e69b6d40_1395374_e608f2d41536b420e23c9a9f217ffa84.webp 760w,
/fr/teaching/lab/intro-unity/images/first-person-objects-to-copy_hu8b0e4f3b2126b182dfe7c755e69b6d40_1395374_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/first-person-objects-to-copy_hu8b0e4f3b2126b182dfe7c755e69b6d40_1395374_46697a23d5bb07de57e7a7d109430a7f.webp"
width="760"
height="458"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;ol start="4">
&lt;li>&lt;strong>Retirez les doublons après le collage.&lt;/strong> Désactivez le GameObject de l’ancienne caméra fixe de &lt;code>UnityBasics&lt;/code> et conservez la &lt;strong>MainCamera copiée&lt;/strong>. Supprimez l’&lt;strong>EventSystem créé dans la partie précédente&lt;/strong> et conservez &lt;strong>UI_EventSystem copié&lt;/strong>. Il doit rester &lt;strong>un seul EventSystem actif, une seule caméra de rendu active portant MainCamera et un seul AudioListener actif&lt;/strong>. Gardez également &lt;strong>PlayerFollowCamera&lt;/strong>, qui pilote la caméra de rendu via Cinemachine. Placez le personnage près de la pile, par exemple X &lt;code>0&lt;/code>, Z &lt;code>-8&lt;/code>, avec son bas juste au-dessus du sol.&lt;/li>
&lt;li>&lt;strong>Tester la navigation et constater ce qui a changé.&lt;/strong> Vérifiez que le layer de &lt;code>Ground&lt;/code> est inclus dans le masque de sol du contrôleur. Lancez Play et cliquez dans Game : testez déplacements, regard, saut et sprint. Le personnage fonctionne, mais le survol rouge et le clic sur les cubes ne fonctionnent plus comme avant : le curseur est verrouillé et la nouvelle caméra n’a pas encore de raycaster. Si le contrôleur produit des sons de pas ou de saut, repérez-les également.&lt;/li>
&lt;li>&lt;strong>Rétablir les interactions au centre de l’écran.&lt;/strong> Arrêtez Play. Ajoutez &lt;strong>Physics Raycaster à la MainCamera copiée&lt;/strong>. Sélectionnez &lt;strong>UI_EventSystem&lt;/strong> et, dans son composant &lt;strong>Input System UI Input Module&lt;/strong>, ouvrez &lt;strong>Advanced&lt;/strong>, puis choisissez &lt;strong>Cursor Lock Behavior = Screen Center&lt;/strong>. Relancez Play en gardant le curseur verrouillé et le regard à la souris : &lt;strong>le cube visé au centre de l’écran devient rouge et le clic gauche le pousse&lt;/strong>. Le Physics Raycaster détecte maintenant l’objet devant vous, au centre de l’image.&lt;/li>
&lt;li>&lt;strong>Retrouver une souris libre.&lt;/strong> Arrêtez Play. Sur &lt;strong>PlayerCapsule&lt;/strong>, dans le composant qui gère les entrées du contrôleur (&lt;strong>Starter Assets Inputs&lt;/strong>), décochez &lt;strong>Cursor Locked&lt;/strong> et &lt;strong>Cursor Input For Look&lt;/strong>. Relancez Play : la souris est visible, ses mouvements ne tournent plus la tête et vous pouvez &lt;strong>survoler et cliquer sur les cubes avec le pointeur&lt;/strong>, comme dans la partie précédente. Le réglage &lt;strong>Screen Center&lt;/strong> n’impose le centre de l’écran que lorsque le curseur est verrouillé.&lt;/li>
&lt;/ol>
&lt;aside class="unity-concept unity-concept--try" role="note" aria-labelledby="unity-concept-81">
&lt;p class="unity-concept__label">À essayer&lt;/p>
&lt;h4 id="unity-concept-81" class="unity-concept__title">Bonus : basculer entre les deux modes&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Ajoutez une &lt;strong>InputAction de type Button&lt;/strong>, liée à une touche de votre choix, pour alterner entre :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Navigation :&lt;/strong> curseur verrouillé, regard à la souris et interactions au centre de l’écran.&lt;/li>
&lt;li>&lt;strong>Interaction libre :&lt;/strong> curseur visible et déverrouillé, regard à la souris désactivé et interactions sous le pointeur.&lt;/li>
&lt;/ul>
&lt;p>Mémorisez le mode dans un booléen et inversez-le à chaque appui, comme pour la rotation. Mettez à jour ensemble les options &lt;strong>Cursor Locked / Cursor Input For Look&lt;/strong> du contrôleur et l’état réel du curseur avec &lt;strong>&lt;code>Cursor.lockState&lt;/code>&lt;/strong> et &lt;strong>&lt;code>Cursor.visible&lt;/code>&lt;/strong>. Gardez &lt;strong>Cursor Lock Behavior = Screen Center&lt;/strong> pour que le même module gère les deux modes.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;p>&lt;a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.20/api/UnityEngine.InputSystem.UI.InputSystemUIInputModule.html#UnityEngine_InputSystem_UI_InputSystemUIInputModule_cursorLockBehavior" target="_blank" rel="noopener">Configuration de Cursor Lock Behavior&lt;/a>.&lt;/p>
&lt;h2 id="création-dynamique-dobjets">Création dynamique d’objets&lt;/h2>
&lt;p>&lt;button type="button" class="unity-term" popovertarget="unity-term-82" popovertargetaction="show" aria-describedby="unity-term-82">Instantiate&lt;/button>&lt;span id="unity-term-82" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Instantiate&lt;/strong>&lt;span>Fonction Unity qui crée une nouvelle instance d’un objet ou d’un prefab pendant l’exécution.&lt;/span>&lt;/span>
crée une copie d’un GameObject ou d’un composant et de son objet. Un prefab permet de créer des objets sans modèle caché dans la scène. Nous allons lancer des cubes jaunes vers l’avant au &lt;strong>clic droit&lt;/strong>.&lt;/p>
&lt;aside class="unity-concept" role="note" aria-labelledby="unity-concept-83">
&lt;p class="unity-concept__label">Notion essentielle&lt;/p>
&lt;h4 id="unity-concept-83" class="unity-concept__title">Instancier : créer un objet pendant l’exécution&lt;/h4>
&lt;div class="unity-concept__body">&lt;p>Les objets de la scène peuvent être placés dans l’éditeur, mais aussi créés pendant l’exécution avec &lt;strong>Instantiate&lt;/strong>. La fonction crée un nouvel objet à partir d’un prefab ; cet exemplaire peut ensuite avoir sa propre position et son propre mouvement.&lt;/p>
&lt;p>&lt;strong>Dans ce TP :&lt;/strong> &lt;code>ProjectilePrefab&lt;/code> reste un asset dans Project. Chaque clic droit crée un projectile dans la scène, lui applique une impulsion, puis &lt;strong>Destroy&lt;/strong> le supprime après un délai. Modifier ce projectile ne modifie pas le modèle de départ.&lt;/p>
&lt;/div>
&lt;/aside>
&lt;ol>
&lt;li>Créez un cube &lt;code>Projectile&lt;/code>, de taille &lt;code>(0.25, 0.25, 0.25)&lt;/code>, avec un matériau URP Lit jaune, &lt;strong>Box Collider&lt;/strong> et &lt;strong>Rigidbody&lt;/strong>, masse &lt;code>1&lt;/code>, gravité activée, Is Kinematic désactivé. Faites-en &lt;code>ProjectilePrefab&lt;/code>, puis supprimez l’instance de la scène. Il ne porte pas &lt;code>RotateCube&lt;/code> ni &lt;code>MouseInteraction&lt;/code>, afin de ne pas recopier les actions et comportements des cibles.&lt;/li>
&lt;li>Dans &lt;code>Assets/Scripts&lt;/code>, créez un &lt;strong>nouveau script &lt;code>CreateOnClick.cs&lt;/code>&lt;/strong> et ajoutez-le à la &lt;strong>caméra portant réellement Camera&lt;/strong>, pas à la cible Cinemachine. Complétez ce script dans les étapes suivantes. Déclarez &lt;code>[SerializeField] private Rigidbody projectilePrefab;&lt;/code> et glissez &lt;code>ProjectilePrefab&lt;/code> dans ce champ : cette référence donne directement accès à la physique.&lt;/li>
&lt;li>Importez &lt;code>UnityEngine.InputSystem&lt;/code> et déclarez une &lt;strong>InputAction nommée &lt;code>fire&lt;/code>&lt;/strong>, de type &lt;strong>Button&lt;/strong>, liée à &lt;code>&amp;lt;Mouse&amp;gt;/rightButton&lt;/code>. Activez-la dans &lt;code>Start()&lt;/code> comme précédemment. Ici, au lieu de vous abonner à &lt;code>performed&lt;/code>, &lt;strong>interrogez l’action dans &lt;code>Update()&lt;/code>&lt;/strong> avec &lt;strong>&lt;code>fire.WasPressedThisFrame()&lt;/code>&lt;/strong> : cette méthode renvoie &lt;code>true&lt;/code> seulement pour l’image où le bouton vient d’être pressé.&lt;/li>
&lt;li>&lt;strong>Calculer la position de départ.&lt;/strong> Dans &lt;code>Update()&lt;/code>, placez les opérations suivantes dans un &lt;strong>&lt;code>if&lt;/code>&lt;/strong> qui vérifie l’appui détecté au point 3. Déclarez une variable locale &lt;code>position&lt;/code> de type &lt;strong>&lt;code>Vector3&lt;/code>&lt;/strong> : partez de la position de la caméra (&lt;code>transform.position&lt;/code>) et ajoutez sa direction avant (&lt;code>transform.forward&lt;/code>) multipliée par &lt;strong>&lt;code>2f&lt;/code>&lt;/strong>. Le projectile apparaîtra ainsi deux unités devant elle.&lt;/li>
&lt;li>&lt;strong>Créer le projectile.&lt;/strong> Appelez &lt;strong>&lt;code>Instantiate&lt;/code>&lt;/strong> avec trois arguments : &lt;code>projectilePrefab&lt;/code>, la position calculée et la rotation de la caméra (&lt;code>transform.rotation&lt;/code>). Stockez le résultat dans une variable locale &lt;strong>&lt;code>projectile&lt;/code> de type &lt;code>Rigidbody&lt;/code>&lt;/strong> pour pouvoir agir sur cette nouvelle instance.&lt;/li>
&lt;li>&lt;strong>Lancer le projectile.&lt;/strong> Comme pour la poussée des cubes, appelez &lt;strong>&lt;code>AddForce&lt;/code>&lt;/strong> sur le Rigidbody créé. Utilisez la direction avant de la caméra multipliée par &lt;strong>&lt;code>12f&lt;/code>&lt;/strong>, avec &lt;strong>&lt;code>ForceMode.Impulse&lt;/code>&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Supprimer le projectile après un délai.&lt;/strong> Appelez &lt;strong>&lt;code>Destroy&lt;/code>&lt;/strong> avec le GameObject de l’instance (&lt;code>projectile.gameObject&lt;/code>) et un délai de &lt;strong>&lt;code>8f&lt;/code>&lt;/strong> secondes. Gardez cet appel dans le même &lt;code>if&lt;/code> : chaque projectile aura ainsi sa propre durée de vie.&lt;/li>
&lt;/ol>
&lt;p>Le jaune vient du matériau du prefab ; vous pouvez aussi changer la couleur du Renderer de l’instance. La position devant le joueur évite de créer le projectile à l’intérieur du personnage. Vérifiez également un espace libre devant la caméra : 2 unités ne garantissent pas d’éviter un mur proche.&lt;/p>
&lt;p>&lt;strong>À observer :&lt;/strong> comparez trajectoires et poussées en modifiant masse et impulsion. Une impulsion est appliquée une seule fois ; une force continue serait appliquée au rythme de la simulation dans &lt;button type="button" class="unity-term" popovertarget="unity-term-84" popovertargetaction="show" aria-describedby="unity-term-84">FixedUpdate&lt;/button>&lt;span id="unity-term-84" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>FixedUpdate&lt;/strong>&lt;span>Méthode appelée au rythme fixe de la simulation physique, indépendamment du nombre d’images affichées.&lt;/span>&lt;/span>
. &lt;code>Destroy&lt;/code> retire l’objet, ici après huit secondes. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Object.Instantiate.html" target="_blank" rel="noopener">Instantiate&lt;/a>, &lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Rigidbody.AddForce.html" target="_blank" rel="noopener">AddForce&lt;/a>.&lt;/p>
&lt;h2 id="charger-une-géométrie">Charger une géométrie&lt;/h2>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Exemple de voiture" srcset="
/fr/teaching/lab/intro-unity/images/figure-07_hu4e125b8f4165e487f7dd7e5e2cf836b4_277848_55d13e50f43781f7497e88c19ac9463e.webp 400w,
/fr/teaching/lab/intro-unity/images/figure-07_hu4e125b8f4165e487f7dd7e5e2cf836b4_277848_77978052ef49e284645d223b076ebba4.webp 760w,
/fr/teaching/lab/intro-unity/images/figure-07_hu4e125b8f4165e487f7dd7e5e2cf836b4_277848_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/figure-07_hu4e125b8f4165e487f7dd7e5e2cf836b4_277848_55d13e50f43781f7497e88c19ac9463e.webp"
width="603"
height="469"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Exemple de colliders" srcset="
/fr/teaching/lab/intro-unity/images/figure-08_hub90ceb0976398944bc0cce9b6c9b5d2a_458821_7f791f9e3693599bdd4af6ae05257262.webp 400w,
/fr/teaching/lab/intro-unity/images/figure-08_hub90ceb0976398944bc0cce9b6c9b5d2a_458821_75132369433444e58d510fd6c666ef6f.webp 760w,
/fr/teaching/lab/intro-unity/images/figure-08_hub90ceb0976398944bc0cce9b6c9b5d2a_458821_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/intro-unity/images/figure-08_hub90ceb0976398944bc0cce9b6c9b5d2a_458821_7f791f9e3693599bdd4af6ae05257262.webp"
width="720"
height="555"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Importez la &lt;strong>Ford Mondeo&lt;/strong>, rendez ses vitres transparentes et définissez ses collisions.&lt;/p>
&lt;ol>
&lt;li>Décompressez &lt;code>Ford_Mondeo.zip&lt;/code> depuis les &lt;a href="resources-unity63.zip">ressources du TP&lt;/a>. Le fichier &lt;code>car.obj&lt;/code> contient le &lt;button type="button" class="unity-term" popovertarget="unity-term-85" popovertargetaction="show" aria-describedby="unity-term-85">maillage&lt;/button>&lt;span id="unity-term-85" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Mesh&lt;/strong>&lt;span>Géométrie d’un objet 3D, décrite par des sommets et des faces. Le mesh visible et la forme de collision peuvent être différents.&lt;/span>&lt;/span>
de la voiture et les fichiers &lt;code>.tga&lt;/code> sont ses textures.&lt;/li>
&lt;li>Dans Project, créez le dossier &lt;code>Assets/Models&lt;/code> (&lt;strong>clic droit dans Assets &amp;gt; Create &amp;gt; Folder&lt;/strong>). Depuis l’explorateur de fichiers, glissez &lt;strong>tout le dossier décompressé &lt;code>Ford_Mondeo&lt;/code>&lt;/strong> dans &lt;code>Assets/Models&lt;/code> dans Project. Attendez la fin de l’import, puis glissez &lt;strong>&lt;code>car.obj&lt;/code> de Project vers Hierarchy&lt;/strong> pour créer une instance dans la scène. Sélectionnez cette instance et réglez son &lt;strong>Transform &amp;gt; Scale à &lt;code>(0.01, 0.01, 0.01)&lt;/code>&lt;/strong> comme point de départ. Vérifiez sa taille en la comparant aux cubes d’un mètre, puis ajustez si nécessaire sa taille, sa rotation et sa position. Les textures des &lt;strong>Base Maps&lt;/strong> sont normalement déjà assignées.&lt;/li>
&lt;li>&lt;strong>Extraire les matériaux pour les modifier.&lt;/strong> Sélectionnez l’asset &lt;strong>&lt;code>car.obj&lt;/code> dans Project&lt;/strong>, puis ouvrez l’onglet &lt;strong>Materials&lt;/strong> de ses &lt;strong>Import Settings&lt;/strong> dans l’Inspector. Les matériaux sont inclus dans le modèle : cliquez sur &lt;strong>Extract Materials…&lt;/strong> et choisissez un dossier, par exemple &lt;code>Assets/Materials/Car&lt;/code>. Ils deviennent des assets de matériau que vous pouvez modifier.&lt;/li>
&lt;li>&lt;strong>Rendre les vitres transparentes.&lt;/strong> Repérez le matériau utilisé par les vitres et sélectionnez le matériau extrait dans Project. Dans son Inspector, avec le shader &lt;strong>Universal Render Pipeline/Lit&lt;/strong>, choisissez &lt;strong>Surface Type = Transparent&lt;/strong> et &lt;strong>Blending Mode = Alpha&lt;/strong>. Ouvrez la couleur de &lt;strong>Base Map&lt;/strong>, puis diminuez sa valeur &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-86" popovertargetaction="show" aria-describedby="unity-term-86">alpha (A)&lt;/button>&lt;span id="unity-term-86" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Alpha&lt;/strong>&lt;span>Composante qui décrit l’opacité : 0 signifie transparent et 1 opaque. Le shader doit aussi être configuré pour la transparence.&lt;/span>&lt;/span>
&lt;/strong>, par exemple à &lt;code>0.3&lt;/code>. Observez la transparence des vitres dans la scène.&lt;/li>
&lt;li>Lancez des cubes sur la voiture et essayez de marcher à travers. Un mesh visible ne fournit pas automatiquement un collider. Ajoutez des &lt;strong>Box Colliders&lt;/strong> pour une approximation simple ou des &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-87" popovertargetaction="show" aria-describedby="unity-term-87">Mesh Colliders&lt;/button>&lt;span id="unity-term-87" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Mesh Collider&lt;/strong>&lt;span>Collider utilisant un mesh comme forme de collision. Les formes non convexes sont adaptées aux décors fixes ; les corps dynamiques demandent d’autres choix.&lt;/span>&lt;/span>
&lt;/strong> sur les parties pertinentes de la voiture immobile.&lt;/li>
&lt;/ol>
&lt;p>Un Mesh Collider non &lt;button type="button" class="unity-term" popovertarget="unity-term-88" popovertargetaction="show" aria-describedby="unity-term-88">convexe&lt;/button>&lt;span id="unity-term-88" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Collider convexe&lt;/strong>&lt;span>Forme de collision sans creux. Unity impose des contraintes aux Mesh Colliders des corps dynamiques ; une approximation convexe est un choix possible.&lt;/span>&lt;/span>
convient à un décor fixe, sans Rigidbody dynamique. Pour une voiture physique mobile, privilégiez des colliders primitifs assemblés ou des Mesh Colliders convexes, avec un Rigidbody sur la racine. Des collisions plus détaillées peuvent coûter plus de calcul. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/mesh-colliders.html" target="_blank" rel="noopener">Mesh Colliders&lt;/a>, &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/urp/lit-shader.html" target="_blank" rel="noopener">URP Lit&lt;/a>.&lt;/p>
&lt;p>&lt;strong>Vérification :&lt;/strong> échelle plausible, textures visibles, vitres transparentes, collisions avec le personnage et les projectiles.&lt;/p>
&lt;h2 id="créer-un-exécutable-pour-la-scène">Créer un exécutable pour la scène&lt;/h2>
&lt;ol>
&lt;li>Arrêtez Play et sauvegardez &lt;code>UnityBasics&lt;/code>.&lt;/li>
&lt;li>Ouvrez &lt;strong>File &amp;gt; &lt;button type="button" class="unity-term" popovertarget="unity-term-89" popovertargetaction="show" aria-describedby="unity-term-89">Build Profiles&lt;/button>&lt;span id="unity-term-89" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Build Profiles&lt;/strong>&lt;span>Configurations d’export qui regroupent la plateforme cible et les réglages utilisés pour construire l’application.&lt;/span>&lt;/span>
&lt;/strong>. Choisissez &lt;strong>Linux&lt;/strong>, &lt;strong>Windows&lt;/strong> ou &lt;strong>macOS&lt;/strong> selon la machine, puis créez/activez son profil si nécessaire. Le module de build correspondant doit être installé via Unity Hub.&lt;/li>
&lt;li>Dans &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-90" popovertargetaction="show" aria-describedby="unity-term-90">Scene List&lt;/button>&lt;span id="unity-term-90" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Scene List&lt;/strong>&lt;span>Liste des scènes incluses dans le build ; la première scène activée est normalement celle chargée au démarrage.&lt;/span>&lt;/span>
&lt;/strong>, ajoutez la scène avec &lt;strong>Add Open Scenes&lt;/strong>. Vérifiez qu’elle est cochée et en premier ; retirez les scènes de démonstration. Un profil peut remplacer la liste partagée : vérifiez celle effectivement utilisée.&lt;/li>
&lt;li>Cliquez sur &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-91" popovertargetaction="show" aria-describedby="unity-term-91">Build&lt;/button>&lt;span id="unity-term-91" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Build&lt;/strong>&lt;span>Application produite à partir du projet pour une plateforme cible. Elle peut fonctionner sans l’éditeur Unity.&lt;/span>&lt;/span>
&lt;/strong>, choisissez un dossier dédié hors de &lt;code>Assets&lt;/code>, par exemple &lt;code>Builds/Linux&lt;/code>, puis lancez l’application. &lt;strong>Build And Run&lt;/strong> l’exécute immédiatement.&lt;/li>
&lt;li>Testez navigation, R, clics, physique et matériaux hors de l’éditeur. Distribuez le &lt;strong>dossier complet du build&lt;/strong>. Explorez &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-92" popovertargetaction="show" aria-describedby="unity-term-92">Player Settings&lt;/button>&lt;span id="unity-term-92" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Player Settings&lt;/strong>&lt;span>Réglages de l’application exportée, comme son nom, sa résolution et les options de la plateforme.&lt;/span>&lt;/span>
&amp;gt; Resolution and Presentation&lt;/strong> pour la résolution et le plein écran.&lt;/li>
&lt;/ol>
&lt;p>La plateforme &lt;strong>Web&lt;/strong> permet également un build pour navigateur avec son module. Il nécessite un serveur HTTP : ouvrir directement le HTML ne suffit pas. Pour cette séance, commencez par le build local. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/build-profiles.html" target="_blank" rel="noopener">Build Profiles&lt;/a>.&lt;/p>
&lt;h2 id="pour-aller-plus-loin">Pour aller plus loin&lt;/h2>
&lt;p>Choisissez une piste pour enrichir &lt;strong>la scène que vous venez de construire&lt;/strong>. Les variations proposées dans le TP — maintenir R, pousser pendant l’appui et changer de mode de souris — constituent un premier prolongement.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Personnaliser les tirs.&lt;/strong> Exposez l’impulsion, la durée de vie et la distance de création du projectile dans l’Inspector avec &lt;code>[SerializeField]&lt;/code>. Comparez plusieurs réglages sans modifier le code.&lt;/li>
&lt;li>&lt;strong>Créer un petit parcours.&lt;/strong> Réutilisez vos prefabs pour placer des obstacles et des cibles. Utilisez les &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/Layers.html" target="_blank" rel="noopener">layers&lt;/a> pour choisir quels objets peuvent entrer en collision ou être visés.&lt;/li>
&lt;li>&lt;strong>Donner une ambiance à la scène.&lt;/strong> Modifiez la &lt;button type="button" class="unity-term" popovertarget="unity-term-93" popovertargetaction="show" aria-describedby="unity-term-93">skybox&lt;/button>&lt;span id="unity-term-93" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Skybox&lt;/strong>&lt;span>Fond qui représente l’environnement lointain de la scène, souvent le ciel.&lt;/span>&lt;/span>
et l’éclairage dans &lt;strong>Window &amp;gt; Rendering &amp;gt; Lighting&lt;/strong>. Pour approfondir, étudiez les objets &lt;strong>Static&lt;/strong> et l’&lt;button type="button" class="unity-term" popovertarget="unity-term-94" popovertargetaction="show" aria-describedby="unity-term-94">éclairage précalculé&lt;/button>&lt;span id="unity-term-94" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Éclairage baked&lt;/strong>&lt;span>Éclairage calculé à l’avance et enregistré dans des ressources, plutôt que recalculé entièrement pendant l’exécution.&lt;/span>&lt;/span>
: ne marquez pas les cubes mobiles comme statiques. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/LightMode-Baked.html" target="_blank" rel="noopener">Éclairage baked&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Ajouter un effet visuel.&lt;/strong> Créez de la fumée avec un &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-95" popovertargetaction="show" aria-describedby="unity-term-95">Particle System&lt;/button>&lt;span id="unity-term-95" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Particle System&lt;/strong>&lt;span>Composant qui anime de nombreuses petites particules pour représenter fumée, feu ou autres effets.&lt;/span>&lt;/span>
&lt;/strong>, puis réglez son émission et sa durée de vie. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/class-ParticleSystem.html" target="_blank" rel="noopener">Documentation&lt;/a>. Explorez ensuite &lt;strong>Visual Effect Graph&lt;/strong> ou des matériaux personnalisés avec &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-96" popovertargetaction="show" aria-describedby="unity-term-96">Shader Graph&lt;/button>&lt;span id="unity-term-96" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Shader Graph&lt;/strong>&lt;span>Outil visuel pour créer des shaders en reliant des nœuds au lieu d’écrire tout le code du shader.&lt;/span>&lt;/span>
&lt;/strong> pour URP.&lt;/li>
&lt;li>&lt;strong>Animer un élément du décor.&lt;/strong> Faites ouvrir une porte avec &lt;strong>Animation et &lt;button type="button" class="unity-term" popovertarget="unity-term-97" popovertargetaction="show" aria-describedby="unity-term-97">Animator&lt;/button>&lt;span id="unity-term-97" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Animator&lt;/strong>&lt;span>Composant qui contrôle la lecture et les transitions des animations à partir d’un Animator Controller.&lt;/span>&lt;/span>
&lt;/strong>. Pour des événements différés, explorez les &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-98" popovertargetaction="show" aria-describedby="unity-term-98">coroutines&lt;/button>&lt;span id="unity-term-98" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>Coroutine&lt;/strong>&lt;span>Méthode pouvant suspendre son exécution avec yield puis reprendre plus tard, par exemple après un délai.&lt;/span>&lt;/span>
&lt;/strong>. &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/animeditor-UsingAnimationEditor.html" target="_blank" rel="noopener">Animation&lt;/a>, &lt;a href="https://learn.unity.com/tutorial/coroutines" target="_blank" rel="noopener">coroutines&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Afficher une information à l’écran.&lt;/strong> Ajoutez une interface indiquant le nombre de projectiles créés. Choisissez &lt;strong>Unity UI&lt;/strong> ou &lt;strong>UI Toolkit&lt;/strong> en vous aidant de la &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/UI-system-compare.html" target="_blank" rel="noopener">comparaison des systèmes d’interface&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>Pour un projet ultérieur, vous pouvez aussi importer un personnage &lt;strong>Humanoid&lt;/strong> et ses animations, étudier l’&lt;strong>Inverse Kinematics&lt;/strong>, comparer un contrôleur personnalisé fondé sur &lt;strong>CharacterController&lt;/strong> ou &lt;strong>Rigidbody&lt;/strong>, ou rendre une voiture pilotable avec &lt;strong>WheelCollider&lt;/strong>. Ces sujets demandent davantage de temps : &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/class-Avatar.html" target="_blank" rel="noopener">Avatar&lt;/a>, &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/InverseKinematics.html" target="_blank" rel="noopener">IK&lt;/a>, &lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/WheelColliderTutorial.html" target="_blank" rel="noopener">véhicules&lt;/a>.&lt;/p>
&lt;p>Pour renforcer vos scripts, explorez &lt;strong>&lt;button type="button" class="unity-term" popovertarget="unity-term-99" popovertargetaction="show" aria-describedby="unity-term-99">RequireComponent&lt;/button>&lt;span id="unity-term-99" class="unity-term-definition" role="tooltip" popover="auto">&lt;strong>RequireComponent&lt;/strong>&lt;span>Attribut C# déclarant les composants nécessaires à un script pour aider Unity à les ajouter lors de son attachement.&lt;/span>&lt;/span>
&lt;/strong>, la vérification des références et la gestion des abonnements lorsqu’un composant est désactivé ou détruit.&lt;/p>
&lt;h2 id="ressources">Ressources&lt;/h2>
&lt;p>&lt;strong>Pour comprendre et programmer :&lt;/strong>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Besoin&lt;/th>
&lt;th>Ressource&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Retrouver une notion ou un réglage de l’éditeur&lt;/td>
&lt;td>&lt;a href="https://docs.unity3d.com/6000.3/Documentation/Manual/" target="_blank" rel="noopener">Manuel Unity 6.3&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Comprendre les arguments d’une méthode C#&lt;/td>
&lt;td>&lt;a href="https://docs.unity3d.com/6000.3/Documentation/ScriptReference/index.html" target="_blank" rel="noopener">Référence de l’API Unity 6.3&lt;/a> : cherchez par exemple &lt;code>Instantiate&lt;/code>, &lt;code>AddForce&lt;/code> ou &lt;code>GetComponent&lt;/code>.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Approfondir les actions et les bindings&lt;/td>
&lt;td>&lt;a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.20/manual/Actions.html" target="_blank" rel="noopener">Documentation Input System&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Continuer avec des exercices guidés&lt;/td>
&lt;td>&lt;a href="https://learn.unity.com/" target="_blank" rel="noopener">Unity Learn&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Retrouver les fichiers utilisés ici&lt;/td>
&lt;td>&lt;a href="resources-unity63.zip">Ressources du TP&lt;/a> et &lt;a href="https://assetstore.unity.com/packages/3d/characters/first-person-third-person-character-controllers-196526" target="_blank" rel="noopener">contrôleur première/troisième personne&lt;/a>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Pour enrichir la scène :&lt;/strong> &lt;a href="https://ambientcg.com/" target="_blank" rel="noopener">ambientCG&lt;/a> pour les textures et matériaux, &lt;a href="https://polyhaven.com/" target="_blank" rel="noopener">Poly Haven&lt;/a> pour les HDRI, textures et modèles, et &lt;a href="https://www.mixamo.com/" target="_blank" rel="noopener">Mixamo&lt;/a> pour les personnages et animations. Avant d’importer un asset, vérifiez ses conditions d’utilisation et, pour un package Unity, sa compatibilité avec &lt;strong>Unity 6.3 / URP&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Pour poursuivre après ce TP :&lt;/strong> &lt;a href="../intro-vr/">Une première application de réalité virtuelle&lt;/a> reprend les bases acquises ici pour découvrir le suivi du casque, les contrôleurs, la téléportation et la manipulation avec OpenXR et XR Interaction Toolkit.&lt;/p>
&lt;h2 id="en-cas-de-blocage">En cas de blocage&lt;/h2>
&lt;p>Commencez par &lt;strong>Console&lt;/strong> : corrigez la première erreur rouge avant de tester à nouveau. Double-cliquez sur le message pour ouvrir la ligne concernée. Si vous demandez de l’aide, indiquez l’étape du TP, le résultat attendu et le message exact.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Symptôme&lt;/th>
&lt;th>Vérifications à faire&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Pas d’autocomplétion Unity&lt;/td>
&lt;td>Reprenez le test au début de &lt;strong>Écrire RotateCube&lt;/strong>. Vérifiez l’éditeur externe et ses extensions, puis rouvrez le script depuis Unity.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Le script ne compile pas ou ne peut pas être ajouté&lt;/td>
&lt;td>Vérifiez le nom du fichier et de la classe, les &lt;code>using&lt;/code>, les accolades et les méthodes demandées par les interfaces.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>R ne fait rien&lt;/td>
&lt;td>Cliquez dans Game. Vérifiez que RotateCube est attaché et activé, que le binding est R et que &lt;code>Start()&lt;/code> contient l’abonnement &lt;strong>et&lt;/strong> l’appel à &lt;code>Enable()&lt;/code>. Vérifiez aussi &lt;strong>Active Input Handling = Input System Package (New)&lt;/strong>.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Pas de survol rouge ni de clic&lt;/td>
&lt;td>Vérifiez le collider du cube, MouseInteraction sur le cube, &lt;strong>Physics Raycaster sur la caméra de rendu active&lt;/strong> et un seul EventSystem avec &lt;strong>Input System UI Input Module&lt;/strong>. En navigation, réglez &lt;strong>Advanced &amp;gt; Cursor Lock Behavior = Screen Center&lt;/strong> pour viser avec le curseur verrouillé.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Le cube devient rouge mais ne bouge pas au clic&lt;/td>
&lt;td>Utilisez le clic gauche. Vérifiez le Rigidbody du cube, &lt;strong>Is Kinematic&lt;/strong> désactivé et le tag &lt;strong>MainCamera&lt;/strong> de la caméra active.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Aucun projectile ou référence manquante&lt;/td>
&lt;td>Vérifiez CreateOnClick sur la caméra de rendu, l’action du clic droit et le champ &lt;strong>Projectile Prefab&lt;/strong>. Le prefab assigné doit avoir un Rigidbody.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Le joueur traverse le sol ou la voiture&lt;/td>
&lt;td>Vérifiez leurs colliders ; pour le sol, vérifiez aussi son layer et le masque de sol du contrôleur.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Matériau rose ou vitres opaques&lt;/td>
&lt;td>Vérifiez le shader &lt;strong>Universal Render Pipeline/Lit&lt;/strong>. Pour les vitres, modifiez le matériau extrait : &lt;strong>Surface Type = Transparent&lt;/strong>, puis diminuez l’alpha de Base Map.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Une modification ne se propage pas aux cubes&lt;/td>
&lt;td>Vérifiez si vous avez modifié le prefab ou une instance et si cette dernière possède un override.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Le build ne montre pas la bonne scène&lt;/td>
&lt;td>Vérifiez la &lt;strong>Scene List&lt;/strong> du profil actif : &lt;code>UnityBasics&lt;/code> doit être cochée et en premier.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table></description></item></channel></rss>