Dans ce tuto pour Unity en français, nous allons créer une intelligence artificielle, pour les créatures ennemis. Nous allons importer un asset qui sera un bon exemple d’ennemi. Celui-ci sera capable de se diriger tout seul vers le joueur. Il évitera les obstacles qui se dresseront sur son passage et quand il sera suffisamment proche, il attaquera.
Présentation du système de navigation de Unity
Voici une traduction de la documentation
Le système de navigation vous permet de créer des personnages qui peuvent se déplacer intelligemment dans le monde en 3D du jeu, en utilisant des navigation meshes (maillages de navigation) créés automatiquement à partir de votre scène. Les obstacles dynamiques vous permettent de modifier la navigation des personnages lors de l’exécution, tandis que les liens en dehors du maillage vous permettent de créer des actions spécifiques telles que l’ouverture de portes ou sauter d’une plateforme.
Créez un nouveau projet 3D : BasicAI.
Pré requis :
- Importer un ennemi, par exemple RPG Monster Partners Polyart
- Téléchargez et ajoutez NavMeshComponents : https://github.com/Unity-Technologies/NavMeshComponents
Le décor
Nous allons créer un décor basique avec quelques obstacles.
Dans Hierarchy
Ajoutez un 3D object > Plane.
- Position : x=0 ; y=0 ; z=0
- Rotation : x=0 ; y=0 ; z=0
- Scale : x=50 ; y=1; z=50
Ajoutez deux 3D object > Cube, nommez-les Wall 1 et Wall 2
Wall 1
- Position : x=-3 ; y=0.5 ; z=8.5
- Rotation : x=0 ; y=0 ; z=0
- Scale : x=10 ; y=1; z=1
Wall 2
- Position : x=3 ; y=0.5 ; z=15
- Rotation : x=0 ; y=0 ; z=0
- Scale : x=10 ; y=1; z=1
Ajoutez un 3D object > Create Empty, nommez-le NavMeshSurface
Ajoutez un composant (Add Component) : choisissez le script NavMeshSurface
Cliquez sur le bouton Bake dans NavMeshSurface. Cela permet de calculer la surface sur laquelle notre IA pourra se déplacer.
Dans Project
Créez un Material, choisissez une couleur verte. Glissez le Material sur le Plane.
Créez un Material, choisissez une couleur bleue. Glissez le Material sur Wall 1, puis sur Wall 2.
Le joueur
Pour faire bouger le joueur, vous pouvez utiliser ce script, c’est un First Person Controller très simple.
L’ennemi
Glissez le Prefab RatAssassin dans Hierarchy.
Ajoutez un composant RigidBody.
Ajoutez un composant CapsuleCollider.
- Center : x = 0 ; y = 0.9 ; z = 0
- Radius = 0.5
- Height = 1.8
Ajoutez un composant NavMeshAgent.
Animator Controller
Dans le composant Animator, double cliquez sur le Controller (RatAssassin).
La fenêtre de l’Animator doit s’ouvrir.
Créez 2 paramètres de type Bool :
- Walk
- Attack
Supprimez toutes les animations sauf IdleBattle, Walk et Attack01
Créez les transitions :
- Entry vers IdleBattle
- IdleBattle vers Walk ; Conditions Walk = true
- IdleBattle vers Attack ; Conditions Attack = true
- Walk vers Attack ; Conditions Attack = true
- Attack vers Walk ; Conditions Walk = true
Ajoutez le script ci-dessous :
(N’oubliez pas d’assigner Player à player de MonstreIA.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MonstreIA : MonoBehaviour
{
public GameObject player;
//Agent de Navigation
NavMeshAgent navMeshAgent;
//Animations
Animator animator;
const string STAND_STATE = "Stand";
const string WALK_STATE = "Walk";
const string ATTACK_STATE = "Attack";
//Action actuelle
public string currentAction;
// Start is called before the first frame update
void Awake()
{
currentAction = STAND_STATE;
navMeshAgent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (player != null)
{
//Est-ce que l'IA se déplace vers le joueur ?
if (MovingToTarget())
{
//En train de marcher
return;
}
//Sinon c'est qu'elle est à distance d'attaque
else
{
Attack();
}
}
}
bool MovingToTarget()
{
//Assigne la destination : le joueur
navMeshAgent.SetDestination(player.transform.position);
//navMeshAgent pas prêt ?
if (navMeshAgent.remainingDistance == 0)
return false;
// navMeshAgent.remainingDistance = distance restante pour atteindre la cible (Player)
// navMeshAgent.stoppingDistance = à quel distance de la cible l'IA doit s'arrête
// (exemple 2 m pour le corps à sorps)
if (navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)
{
if (currentAction != WALK_STATE)
Walk();
}
else
{
//Si arrivé à bonne distance, regarde vers le joueur
RotateToTarget(player.transform);
return false;
}
return true;
}
//Walk = Marcher
void Walk()
{
//Réinitialise les paramètres de l'animator
ResetAnimation();
//L'action est maintenant "Walk"
currentAction = WALK_STATE;
//Le paramètre "Walk" de l'animator = true
animator.SetBool(WALK_STATE, true);
}
//Attack = Attaquer
void Attack()
{
//Réinitialise les paramètres de l'animator
ResetAnimation();
//L'action est maintenant "Attack"
currentAction = ATTACK_STATE;
//Le paramètre "Attack" de l'animator = true
animator.SetBool(ATTACK_STATE, true);
}
private void ResetAnimation()
{
animator.SetBool(WALK_STATE, false);
animator.SetBool(ATTACK_STATE, false);
}
//Permet de tout le temps regarder en direction de la cible
private void RotateToTarget(Transform target)
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 3f);
}
}






