Voici le premier de deux tutoriels consacrés à l’orientation d’un objet vers un autre dans Unity ; plus précisément, nous allons voir comment faire en sorte que le modèle 3D d’une caméra de surveillance s’oriente automatiquement vers le Player, en suivant ses déplacements dans la scène.


L'audio de ce tutoriel n'est pas disponible en Français. Vous pouvez regarder ci-dessous la vidéo avec l'audio en Anglais et des sous-titres en Français, en Anglais et dans d’autres langues. Sous la vidéo, vous trouverez la transcription traduite en Français.


Transcription de la vidéo

Bonjour à tous !

Voici le premier de deux tutoriels consacrés à l’orientation d’un objet vers un autre dans Unity ; plus précisément, nous allons voir comment faire en sorte que le modèle 3D d’une caméra de surveillance s’oriente automatiquement vers le Player, en suivant ses déplacements dans la scène.

Ce tutoriel a été réalisé avec Unity 2022 et est divisé en deux parties.

Dans cette première partie, nous analyserons le problème et l’aborderons en utilisant la méthode Rotate afin d’obtenir une rotation instantanée de la caméra.

Dans la seconde partie, nous utiliserons les quaternions et la méthode Slerp pour créer des rotations plus fluides et progressives.

Analysons le problème à résoudre avant de passer à l’implémentation.

La caméra ne peut tourner qu’autour de son axe vertical local ; nous pouvons donc ramener le problème à un plan 2D. Pour rendre cet aspect plus clair, je cadre la scène depuis la vue TOP en mode Orthogonal.

Le modèle 3D de la caméra de surveillance ainsi que le Player possèdent, comme tous les game objects, des coordonnées de Position XYZ qui identifient leur position dans la scène.

Nous ne nous intéressons pas à la coordonnée position.y, car la caméra ne peut tourner qu’autour de cet axe LOCAL ; nous ne considérerons donc que les coordonnées x et z, comme si les deux objets se trouvaient sur le même plan, avec la même valeur pour leur coordonnée y.

Dans notre cas, la caméra de surveillance peut en outre être considérée comme l’origine du système de référence, c’est à dire le point 0,0 d’un plan cartésien.

De plus, nous pouvons considérer la direction cadrée par la caméra, qui correspond ici à l’axe Y LOCAL négatif, comme l’un des axes cartésiens.

Nous pouvons alors identifier la direction qui relie la caméra virtuelle à la position du Player dans la scène. Il s’agit simplement d’un vecteur, que nous considérerons également en deux dimensions, c’est à dire GLOBAL X et Z.

Il en découle que la rotation à appliquer à la caméra de surveillance est donnée par l’angle qui sépare l’orientation de l’asset, donc son axe Y local négatif, et le vecteur idéal reliant la caméra de surveillance au Player. En déterminant cet angle, nous obtiendrons la rotation à appliquer au modèle 3D autour de son axe vertical local.

Nous avons beaucoup de chance : il existe une fonction mathématique appelée arctangente à deux arguments, implémentée par la méthode Atan2 dans Mathf, qui calcule précisément cet angle en prenant comme paramètre le vecteur direction, obtenu par la différence entre les coordonnées des deux points.

Plus précisément, Atan2 considère l’angle entre l’axe X du plan cartésien et le vecteur direction entre l’origine et la cible.

Dans notre cas, l’origine est donnée par les coordonnées X et Z du modèle 3D de la caméra de surveillance. Les coordonnées de la cible seront donc les différences de coordonnées entre la caméra et le Player, tandis que l’axe X coïncide avec l’axe Y local négatif de la caméra.

La fonction prend les deux paramètres dans l’ordre inverse : dans le plan cartésien, nous avons atan2(y,x). Dans notre cas, en tenant compte du système de référence de Unity, où l’axe x est latéral, l’axe z est frontal et l’axe y est vertical, que nous n’utilisons pas ici, nous écrirons atan2(x, z).

La documentation en ligne de Unity indique que Mathf.Atan2 reçoit les coordonnées y et x, qui dans notre cas seront x et z, et renvoie une valeur float correspondant à l’angle en radians dont la tangente est y/x.

La fonction Rotate dans Unity attend un angle de rotation EN DEGRÉS ; nous devrons donc tenir compte de cette différence d’unité de mesure et effectuer la conversion nécessaire lors de l’écriture du code.

Maintenant que nous avons analysé le problème et sa solution, passons à la première implémentation : la rotation instantanée avec Rotate.

Je crée d’abord un nouveau script C# appelé LookAtObject, que j’associe à la caméra de surveillance réelle. Je parle de caméra réelle car cet asset est en réalité composé de trois éléments : une base fixée au mur, un pivot et la caméra.

Nous voulons que la caméra tourne autour de SON axe vertical, c’est à dire autour de son axe vertical LOCAL.

Dans l’univers virtuel de Unity, l’axe vertical GLOBAL est l’axe y, mais chaque objet peut posséder son propre système de référence LOCAL. Dans le cas du modèle 3D de la caméra de surveillance, il s’agit de l’axe Z LOCAL, comme on peut le constater en passant en mode d’affichage LOCAL dans l’éditeur Unity.

Cette distinction introduit une légère complexité dans notre projet : nous devrons calculer l’angle de rotation sur le plan global de la scène, en utilisant les coordonnées X et Z des objets, puis effectuer la rotation autour de l’axe vertical local de l’asset.

Commençons par créer une référence vers l’objet à suivre, en déclarant une variable Transform appelée objectA, que nous associerons au Player dans l’Inspector.

[SerializeField] private Transform objectA;

Cela fait, nous pouvons passer directement à Update pour implémenter la solution décrite précédemment. Je rappelle que l’axe vertical LOCAL de la caméra correspond à son axe Z.

Trois lignes de code suffisent.

Dans la première, nous calculerons l’angle qui sépare l’orientation actuelle de la caméra de celle qu’elle devrait avoir pour pointer vers l’objet.

Dans la deuxième, nous calculerons la quantité de rotation à effectuer autour de l’axe Z local de la caméra afin d’atteindre l’orientation souhaitée.

Dans la troisième, nous effectuerons la rotation réelle à l’aide de la méthode Rotate, à laquelle nous fournirons deux paramètres : le vecteur vertical local et la quantité de rotation à appliquer autour de ce vecteur.

Commençons par calculer l’angle entre l’orientation de la caméra de surveillance et celle qu’elle doit adopter, en utilisant la fonction Atan2 de Mathf, qui renvoie une valeur en radians que nous convertirons en degrés.

Nous avons vu que, dans le plan 2D, Atan2 prend deux paramètres : la différence entre les coordonnées Y et la différence entre les coordonnées X des deux points, dans l’ordre cible puis observateur.

Dans notre scénario, avec le système de coordonnées global de Unity, où X et Z définissent le plan 2D tandis que GLOBAL Y représente l’axe vertical de la scène, nous écrirons :

float theta = Mathf.Atan2((objectA.transform.position.x - transform.position.x), (objectA.transform.position.z - transform.position.z)) * Mathf.Rad2Deg;

Nous avons ajouté à la fin * Mathf.Rad2Deg pour convertir le résultat en degrés.

Nous pouvons ensuite passer à la deuxième instruction : calculer la rotation à effectuer en degrés, ce qui se fait simplement avec :

float deltaAngle = Mathf.DeltaAngle(transform.eulerAngles.z, theta);

où transform.eulerAngles.z représente l’orientation actuelle de la caméra de surveillance, tandis que theta représente l’orientation calculée à l’étape précédente qu’elle doit adopter.

La troisième et dernière instruction permet de faire tourner la caméra de surveillance :

transform.Rotate(Vector3.forward, deltaAngle);

Notez que j’ai utilisé Vector3.forward, qui identifie l’axe Z LOCAL de l’objet, comme vecteur autour duquel effectuer la rotation. Cela s’explique par le fait que, dans ce modèle 3D spécifique, l’axe Z LOCAL ne correspond pas à l’avant et à l’arrière mais à l’axe vertical local de l’objet.

Enregistrez le script, revenez dans l’éditeur Unity et appuyez sur Play pour vérifier le résultat final.

NOTE - Si vous constatez que la caméra de surveillance ne pointe pas vers la cible, assurez vous que les valeurs initiales XYZ Rotation de la caméra de surveillance sont réglées sur 0 dans l’Inspector, puis réessayez.

Pour résumer, dans cette première partie, nous avons analysé le problème à résoudre et vu comment considérer les deux objets sur un même plan, comment calculer le vecteur direction et surtout comment l’appliquer au cas spécifique de la caméra de surveillance en tenant compte de son système de référence local.

Nous avons ensuite appliqué une rotation instantanée à l’objet afin qu’il pointe vers le Player à chaque frame du jeu, en utilisant la fonction Rotate.

Dans la prochaine partie, nous verrons comment calculer les quaternions de rotation et utiliser la fonction Slerp afin de faire tourner l’objet plus lentement.

Rechercher dans les Tutoriels

Saisissez une expression ou plusieurs mots-clés séparés par des virgules.

Modèles 3D, tutoriels et ressources en infographie de Francesco Milanese. Les licences d’utilisation des modèles 3D peuvent être achetées sur les boutiques externes accessibles depuis leurs pages respectives, conformément aux conditions de licence applicables. Francesco Milanese — Numéro de TVA : 06321250877. Contact : info@francescomilanese.com


POLITIQUE GENERALE DE CONFIDENTIALITE ET D'UTILISATION DES COOKIES