Les bases d’Unity 3D

▶ Lancer Unity sur les PC de l’école
▶ Documentation et tutoriels
- Documentation officielle : https://docs.unity3d.com/
- Tutoriels Unity Learn : https://unity3d.com/fr/learn/tutorials/
Table des matières
L’éditeur d’Unity 3D
Lorsque vous créez un projet, vous obtenez par défaut dans la scène une caméra (Main Camera) et une lumière pour éclairer la scène 3D (Directional Light). La fenêtre de l’éditeur se présente alors de la façon suivante :

Cette fenêtre de l’éditeur est composée des éléments suivants :
- L’éditeur graphique de la scène 3D permettant de manipuler directement des objets de la scène.
- L’arborescence de la scène permettant de visualiser la hiérarchie des objets présents dans la scène.
- L’inspecteur permettant de voir les différents scripts rattachés à l’objet sélectionné (par 1 ou 2) et de modifier leurs paramètres.
- L’explorateur de projet permettant de voir les différents composants du projet et de les ajouter à la scène par un simple glisser-déposer. Pour l’instant, il y a seulement la scène dans le projet.
- Les boutons permettant de lancer l’exécution de la scène 3D dans l’éditeur, ce qui est très utile pour tester et déboguer la scène (nous verrons plus tard comment créer un exécutable pour la scène).
- La visualisation de la scène 3D à partir du point de vue de la caméra virtuelle. L’éditeur bascule automatiquement sur cette visualisation lorsque l’exécution de la scène est lancée.
- La console permettant de voir les messages d’erreurs ou les journaux (logs) lors de l’exécution de la scène.
Les interactions dans l’éditeur graphique peuvent se faire à partir des boutons suivants :

Voir https://docs.unity3d.com/Manual/SceneViewNavigation.html et https://docs.unity3d.com/Manual/PositioningGameObjects.html pour plus d’informations.
Créer une scène simple
Pour commencer, nous allons créer une application toute simple qui affiche plusieurs cubes de couleur bleue à des positions différentes :
- Insérer un plan dans la scène pour créer un sol (GameObject > 3D Object > Plane). Au moyen de l’inspecteur (3), placer ce plan aux coordonnées (0, 0, 0) et vérifier qu’il est bien visible par la caméra. Agrandir ce plan en jouant sur l’échelle pour qu’il ait une longueur et une largeur de 100 mètres et vérifier qu’il est bien visible à l’infini lorsque l’on prend la vue de la caméra.
- Ajouter un cube dans la scène (GameObject > 3D Object > Cube) et le placer pour qu’il soit visible par la caméra.
- Créer un matériau pour donner une couleur au cube (Assets > Create > Material). Un nouveau composant est créé dans le projet (4) : donnez-lui un nom. Puis modifiez sa couleur dans l’inspecteur pour obtenir le bleu de l’image suivante. Ensuite glisser-déposer le matériau à partir de l’explorateur de projet (4) sur le cube dans l’arborescence de la scène (2). Le cube devrait prendre la couleur bleue dans l’éditeur graphique (1).
- Ajouter une texture sur le plan : télécharger la texture grid_grey.png sur le site du cours, aller dans (Assets > Import New Asset…) et choisir la texture. Glisser-déposer la texture à partir de l’explorateur de projet (4) sur le plan dans l’arborescence de la scène (2). Puis sélectionner le plan dans l’arborescence de la scène (2) et modifier les paramètres du matériau dans l’inspecteur (3) afin d’obtenir la même texture du sol que dans l’image ci-dessous. Il faudra en particulier jouer sur le nombre de fois que la texture est répétée (« tiling »).
- Déplacer le cube et la caméra afin d’obtenir une image similaire lorsque vous exécutez la scène :

Ajouter un comportement physique au cube : sélectionner le cube et lui ajouter un Rigidbody (Component > Physics > Rigidbody). Observer ce qui se passe lorsque vous exécutez la scène.
Glisser-déposer le cube depuis l’arborescence de la scène (2) vers l’explorateur de projet (4) : cela va créer un « Prefab » à partir du cube (cf. icône bleue), que vous devrez renommer (CubePrefab par exemple). Puis, par l’opération inverse, insérer 11 autres cubes à partir de ce modèle dans la scène et déplacer les instances de ce cube afin d’obtenir la même disposition que dans l’image.

- Exécuter la scène.
- Sélectionner le CubePrefab dans l’explorateur de projet (4) et modifier les paramètres de son Rigidbody afin de changer son comportement physique (en particulier, la masse « Mass » et la friction « Drag »). Exécuter la scène avec plusieurs paramètres différents. Qu’observez-vous ?
Animer un objet de la scène
Des scripts en C# permettent de donner un comportement aux objets. Nous allons donc créer un nouveau script C# permettant de faire tourner les cubes que nous avons créés :
- Créer un nouveau script (Assets > Create > C# Script) que vous nommerez RotateCube.
- L’éditer en double cliquant dessus.
- La fonction Update(), qui est héritée de la classe MonoBehaviour, est appelée à chaque pas de temps lors de l’exécution de la scène. Dans cette fonction Update(), effectuer une rotation de 3° selon l’axe vertical (Y). Pour cela, vous pourrez accéder à la position de l’objet auquel le script sera associé au travers de l’attribut transform (déjà défini dans la classe mère MonoBehaviour). Vous pourrez utiliser l’auto-complétion pour voir les fonctions que l’on peut appliquer à cet attribut transform et trouver la fonction qui permette d’effectuer la bonne rotation.
- Ajouter le script au CubePrefab par glisser-déposer sur l’icône du Prefab dans l’explorateur de projet (4). Noter l’apparition du script en tant que composant dans l’inspecteur (3) : on peut le désactiver ou le supprimer. Noter également que toutes les instances de CubePrefab ont été modifiées par cet ajout.
- Exécuter la scène.
- Pour plus de généricité du script, ajouter un attribut public dans la classe RotateCube avant la fonction Start() :
public float speed = 3.0f; - Modifier le script en conséquence.
- Vous remarquerez l’apparition de cet attribut dans l’inspecteur (3), ce qui permet de modifier la valeur de la vitesse de rotation sans éditer le script à chaque fois. Noter que la valeur 3.0f est la valeur par défaut lorsque l’on ajoute le script à un nouvel objet.
- Tester avec différentes valeurs.
Gestion des interactions
Unity 3D permet de capter les entrées de base comme les appuis sur les touches du clavier ou les actions de la souris. Cependant, afin de permettre une plus grande généricité et de ne pas coder en dur toutes les commandes dans les scripts, Unity 3D propose un système de gestionnaire d’Input. Pour plus d’information, voir la documentation accessible à l’adresse suivante : https://docs.unity3d.com/Packages/com.unity.inputsystem@1.4/manual/index.html
Nous voulons donc maintenant modifier le script qui fait tourner les cubes pour que l’on puisse activer et désactiver la rotation. Par défaut, la rotation sera désactivée. Lorsque l’utilisateur appuiera sur la touche « r » (et la relâchera ensuite), les cubes se mettront à tourner. Puis lorsqu’il appuiera à nouveau sur la touche « r » (et la relâchera ensuite), les cubes s’arrêteront de tourner, et ainsi de suite : dès que la touche « r » est appuyée, les cubes changeront leur comportement. Pour cela :
- Installer et activer l’Input System package dans le gestionnaire de paquets.
- Ajouter l’import du package dans votre script :
using UnityEngine.InputSystem; - Créer un attribut public de type InputAction nommé activateRotation (il existe d’autres façons de gérer les actions dans Unity : https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/ActionAssets.html).
- Dans l’inspecteur (3), configurer l’action en la liant à l’appui sur un bouton :
+ > Add Bindingpuis en paramétrant ce binding : Path > Keyboard > By Character Map To Key > R. - Pour utiliser l’événement dans votre script, vous devez d’abord l’activer :
activateRotation.Enable();puis lier l’un des callbacks suivants à une fonction ou un lambda :
action.started += ctx => /* Action was started */;
action.performed += ctx => /* Action was performed */;
action.canceled += ctx => /* Action was canceled */;
- Pour vérifier le bon fonctionnement de votre script, vous pouvez afficher dans la console de l’éditeur (7) un message chaque fois que la touche « r » est appuyée. Pour cela, vous pourrez utiliser la syntaxe suivante :
Debug.Log("votre message");.
Programmation d’interaction simple avec la souris
Nous souhaitons créer un nouveau script permettant de pousser les cubes lorsque l’on clique dessus et de changer la couleur du cube lorsque l’on passe la souris sur ce cube. Pour cela, nous allons implémenter les interfaces IPointerClickHandler, IPointerEnterHandler et IPointerExitHandler du namespace UnityEngine.EventSystems :
- Ajoutez un GameObject > UI > EventSystem à votre scène, et cliquez sur le bouton Replace with InputSystemUIInputModule dans l’inspecteur (3).
- Ajoutez un composant Event > Physics Raycaster à votre caméra. Ceci permettra de générer les évènements lors du survol de l’objet.
- Créer un nouveau script C# que vous nommerez MouseInteraction.
- Ajouter l’import du package dans votre script :
using UnityEngine.EventSystems;. - Utilisez ce script pour implémenter IPointerClickHandler, IPointerEnterHandler et IPointerExitHandler. Les fonctions correspondantes à implémenter sont OnPointerClick, OnPointerEnter et OnPointerExit.
- Créer deux attributs privés de type Rigidbody et Renderer afin de pouvoir stocker des liens vers le Rigidbody (pour la physique) et le Renderer de l’objet (pour pouvoir accéder au matériau et changer la couleur).
- Dans la fonction Start(), initialiser vos deux attributs en utilisant les fonctions :
GetComponent<Rigidbody>()etGetComponent<Renderer>(). - Pour pousser le cube, vous pourrez appliquer une force sur son Rigidbody en utilisant la fonction
AddForce(...). L’attributCamera.mainpermet d’accéder à la caméra principale etCamera.main.transform.forwarddonne le vecteur pointant vers l’avant de la caméra. Cependant, il faudra le multiplier pour obtenir une force suffisante. - Pour changer la couleur, vous pourrez accéder à l’attribut
.materialsur le Renderer et à l’attribut.colorsur le matériau :rend.material.color. Cela devrait vous permettre à la fois de stocker la couleur initiale de l’objet (pour la remettre une fois que la souris aura quitté le cube) et de changer cette couleur en utilisant une couleur prédéfinie comme :Color.red.
Pour plus d’information sur la classe MonoBehaviour et ses fonctions, aller voir la documentation : https://docs.unity3d.com/ScriptReference/MonoBehaviour.html
Navigation en réutilisant des scripts d’interaction clavier/souris
Unity 3D propose plusieurs composants pour gérer différents types d’interaction de base. Dans cette partie, nous allons ajouter un composant pour pouvoir naviguer dans la scène à la façon d’un FPS :
- Télécharger et importer le module « First Person Character Controller » (Window > Asset Store, puis chercher le module « Standard Assets - First Person Character Controller »).
- Dans l’explorateur de projet, suivre le chemin suivant :
Assets > Starter Assets > FirstPersonController > Prefabs. Ajouter le Prefab nommé NestedParent_Unpack dans l’arborescence de la scène (2). Il possède sa propre Main Camera : désactiver la Main Camera utilisée précédemment en décochant la case dans l’inspecteur (3).

- Modifier la position du NestedParent_Unpack pour avoir une vue à la 1ère personne de la pile de cubes, en étant posé sur le plan.
- Exécuter la scène, tester les commandes (flèches, barre d’espace, souris) et écouter aussi le son produit.
- Si vous souhaitez pouvoir continuer à utiliser les actions souris codées précédemment, vous pouvez décocher l’option Cursor Locked dans l’inspecteur (3) pour le script suivant : NestedParent_Unpack > PlayerCapsule > Starter Assets Inputs. Il vous faudra aussi penser à remettre un Physics Raycaster sur la nouvelle caméra.
Création dynamique d’objets
Nous voulons maintenant créer dynamiquement des objets dans la scène 3D. Pour cela, Unity 3D propose une fonction Instantiate(GameObject obj) qui permet d’instancier dynamiquement dans la scène une copie de l’objet passé en paramètre. L’objet passé en paramètre peut être un objet déjà présent dans la scène ou bien un Prefab si l’on ne veut pas que l’objet soit déjà dans la scène.
Nous souhaitons faire en sorte que des cubes jaunes soient lancés dans la direction de la caméra lorsque l’utilisateur appuie sur le bouton droit de la souris :
Créer un nouveau script C# que vous nommerez CreateOnClick.
Ajouter ce script au NestedParent_Unpack > PlayerCapsule > PlayerCameraRoot (l’objet qui suit les mouvements de la souris). C’est aussi lui qui porte la caméra.
Créer un attribut public
GameObject aCopierqui vous permettra de stocker une référence sur l’objet à instancier. Il faudra initialiser cet attribut en faisant un glisser-déposer du CubePrefab dans le champ de l’attribut dans l’inspecteur (3) lorsque l’on a sélectionné le PlayerCameraRoot.L’appui sur le clic droit peut être traité comme l’appui sur une touche (comme pour l’action « ActivateRotation »).
À chaque clic droit :
- Instancier un nouveau cube avec la fonction
Instantiate(GameObject obj); - Changer sa couleur ;
- Le placer devant le PlayerCapsule, sinon il sera éjecté dans n’importe quelle direction (collision avec le PlayerCapsule) ;
- Lui appliquer une force pour le lancer en avant.
- Instancier un nouveau cube avec la fonction
Noter que l’on peut aussi supprimer des objets de la scène grâce à la fonction Destroy(GameObject obj).
Charger une géométrie


Nous souhaitons charger le modèle 3D d’une voiture avec des textures plaquées dessus :
- Télécharger l’archive Ford_Mondeo.zip sur le site du cours. Décompresser cette archive. Elle contient un fichier .obj décrivant le maillage (mesh), un fichier .mtl décrivant les couleurs et les placements des textures, ainsi que les images de texture .tga.
- Effectuer un glisser-déposer de tout le dossier contenant les différents fichiers du modèle dans l’explorateur de projet (4). Le modèle devrait être chargé dans Unity 3D.
- Glisser-déposer le modèle dans l’arborescence de la scène (2) pour l’ajouter à la scène. Ajuster sa taille pour qu’il soit à la même échelle que les cubes et sa position pour qu’il se trouve près de la pile de cubes.
- Le chargement de nouveaux modèles 3D souffre souvent de petits problèmes de compatibilité dans toutes les librairies 3D. Observer qu’ici, la transparence des vitres de la voiture n’a pas été conservée. Trouver le matériau qui correspond aux vitres et changer son Rendering Mode, ainsi que la composante alpha (A) de la couleur de la Main Maps afin de rendre les vitres transparentes.
- Essayer de lancer des cubes sur la voiture ou de marcher au travers. Qu’observez-vous ? Pourquoi ?
- Trouver une solution pour régler ce problème. Vous pourrez utiliser des Box Colliders que vous placerez vous-même ou des Mesh Colliders que vous ajouterez aux parties adéquates de la voiture (cf. images sur la page suivante). La seconde solution est plus précise, mais plus coûteuse en temps de calcul.
Créer un exécutable pour la scène
Enfin, nous voulons créer un exécutable pour cette scène afin de pouvoir visualiser la scène en plein écran et éventuellement de la distribuer :
- Aller dans File > Build Settings….
- Sélectionner la cible PC, Mac & Linux Standalone. Observez qu’il y a d’autres cibles intéressantes comme WebGL (cf. l’exécutable de la scène du tutoriel sur le site du cours).
- Cliquer sur Build.
- Tester votre exécutable.
Vous pouvez ensuite cliquer sur Player Settings… en bas de la fenêtre Build Settings… et explorer les différents paramètres du player (fenêtre de dialogue au lancement, résolution, etc.).
Pour aller plus loin
Explorer les Assets, les GameObjects, les Components et la documentation pour ajouter des propriétés ou des animations à votre scène (i.e. particules, collisions…).
En particulier, vous pouvez charger le package Vehicles, tester et essayer de comprendre comment fonctionnent les différents véhicules.
Les éléments suivants dépassent le cadre de « l’initiation à Unity » mais sont néanmoins abordables en lisant attentivement les liens suggérés :
- Changer la skybox et d’autres paramètres de rendu (Window > Rendering > Lighting Settings).
- Modifier les rendus avec des shaders et des textures personnalisés (cf. cours sur les shaders).
- Rendre static (https://docs.unity3d.com/Manual/StaticObjects.html) les objets qui ne bougent pas ou baker (https://docs.unity3d.com/Manual/LightMode-Baked.html) les lumières pour optimiser les performances.
- Ajouter des particules (https://docs.unity3d.com/Manual/class-ParticleSystem.html) (permettent d’afficher du feu, de l’eau, du brouillard, etc.). Des exemples peuvent être trouvés sur l’Asset Store.
- Utiliser les layers (https://docs.unity3d.com/Manual/Layers.html) pour modifier l’affichage et l’effet des lumières sur certains éléments.
- Ajouter des animations (cf. Animations & Animators : https://docs.unity3d.com/Manual/animeditor-UsingAnimationEditor.html).
- Utiliser des avatars (https://docs.unity3d.com/2017.1/Documentation/Manual/class-Avatar.html).
- Voir des mouvements d’Inverse Kinematics (https://docs.unity3d.com/Manual/InverseKinematics.html).
- Utiliser des coroutines (https://learn.unity.com/tutorial/coroutines) pour gérer des évènements sur des temps plus longs.
- Créer une interface utilisateur (https://docs.unity3d.com/Manual/UISystem.html).
- Utiliser un contrôleur personnalisé.
- Sécurisez votre code en utilisant des SerializeField ou encore RequiredComponent.
Ressources
Documentation
Textures
Skybox
Modèles 3D
Avatars
Assets utiles