Page 1 sur 1

[RESOLU][DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 14:34
par Darym
Bonjour!

Nouveau sur ce forum je commence à écrire ici car j'ai un soucis qui me bloque...

J'essaye de faire un petit Tower Defense un peu différent: Mes IA sont des visiteurs de musée qui doivent visiter un musée et admirer les œuvres.
L'idée étant que le joueur va créer le tracé du musée (en créant des couloirs) et en plaçant des œuvres. Avant de voir arriver des vagues de touristes (mes IA) pour visiter ce musée.
Évidemment les œuvres sont des objectifs pour l'IA, qui doit aller vers l'objectif le plus proche puis se diriger vers la suivante.
Une fois toutes les œuvres visités, l'IA se dirige vers la sortie.
Mais tout ce petit GD est gêné par un souci,
Si mon IA recense bien tous les objets ayant le tag "Objectif" dans une liste, lorsque je veux supprimer l'objectif atteint de la liste, le script enlève TOUS les composant de la liste. Rendant mon IA immobile (ou se dirigeant vers un objectif qui n'est pas le plus proche avant de s’arrêter)

Pouvez-vous m'aider à comprendre quel est le problème?
Voici une image de ma scène:
Screen_MR.PNG
Screen_MR.PNG (232.99 Kio) Consulté 5036 fois
Et voici mon script à l'heure actuelle:

_________________________________________________________________________

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AI_Test_Interest_New : MonoBehaviour
{
    private Vector3 targetPosition; // Vector pour diriger l'IA vers le point le plus proche

    private NavMeshAgent directionNavAgent;

    public List<GameObject> Targets;//liste d'objectif

    public GameObject closest; //Censé être la cible la plus proche

    public GameObject Actual; //Censé être la cible atteinte par l'IA

    public bool TargetGet = false; // Pour savoir si l'IA a touché le trigger de l'objectif.

    public bool Atteint = false; // Bool secondaire sans doute inutile pour savoir si l'IA a atteint l'objectif et est prêt à repartir vers l'objectif suivant apres avoir retiré l'objectif attein précedemment.

    void Start()
    {
        FindTargets(); // charge toutes les entité avec le tag objectif dans la liste dés le départ
    }
    void Update()
    {
        MoveToClosest(); // placé dans le update pour le moment pour pousser un dplacement constant
        if (TargetGet == true)
        {
            ChangeTarget();
            //BUT : retirer l'objet actuel de la liste pour le remplacer par le secon plus proche.
            //QUESTION : desactiver le collider pour eviter qu'il prenne d'emblée le script ontriggerenter?

        }
        if (Atteint == true)
        {
            FindClosestTarget(); // une fois le changement fait, retrouve la cible la plus proche
            Debug.Log("change");
           
        }
    }
    void MoveToClosest() // Pour se deplacer vers la cible la plus proche
    {
        directionNavAgent = GetComponent<NavMeshAgent>();
        FindClosestTarget();
        directionNavAgent.destination = targetPosition;

    }
    void OnTriggerEnter(Collider other) // Active le bool TargetGet
    {
        if (other.tag == "Objectif")
        {
            Debug.Log("Pouti");
            TargetGet = true;

        }
    }
    void FindTargets() // Trouve les objets ayant le tag "Objectif"
    {
        Targets = new List<GameObject>();
        foreach (GameObject go in GameObject.FindGameObjectsWithTag("Objectif"))
        {
            Targets.Add(go);
        }
        //Targets.Add(GameObject.FindGameObjectWithTag("Objectif"));


    }
    void ChangeTarget() // Enleve la Target la plus proche pour la remplacer par la suivante.
    {
        float distance = Mathf.Infinity;
        Vector3 Position = transform.position;


        foreach (GameObject go in Targets) // reprend le code du FindTarget, car au moment ou le script est lancé le plus proche est forcemment celui à retirer de la liste
        {

            Vector3 diff = go.transform.position - Position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance)
            {
                Actual = go;
                Targets.Remove(Actual);
                //Targets.Remove(Actual);
                Atteint = true;
            }
            

        }

        
        Debug.Log("Removed");
       
    }
    void FindClosestTarget() // Trouve la cible la plus proche
    {
        float distance = Mathf.Infinity;
        Vector3 Position = transform.position;
        int i = (Targets.Count);
        Debug.Log(i);

        foreach (GameObject go in Targets)
        {

            Vector3 diff = go.transform.position - Position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance)
            {
                closest = go;
                distance = curDistance;
                targetPosition = closest.transform.position;
            }
           
        }

        return;
    }
    }

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 17:57
par Max
Hello,

Je ne comprends pas trop ta logique.
Tu as un Navmeshagent, auquel tu assignes un objectif ( MoveToClosest). Mais pour savoir si l'objectif est atteint, tu parcours l'ensemble des targets pour trouver la cible la plus proche. C'est volontaire ? Pourquoi ne pas faire une simple comparaison juste entre le Navmeshagent et le target courant ?

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 18:17
par Darym
Ma logique n'est peut être pas bonne de base...

Comme le joueur pose lui même autant d'objectif que l'on veut, l'IA doit checker ce qu'il y a encore comme objectif:

IA check les objectifs existant et les place dans une liste
IA se dirige vers Objectif le plus proche (A)
IA Atteint Objectif A
IA Retire Objectif A de sa liste et se dirige vers le nouvel Objectif le plus proche (B)
IA Atteint Objectif B
IA Retire Objectif B de sa liste et se dirige vers le nouvel Objectif le plus proche (C)
...

Si le compteur de la liste atteint 0, l'IA se dirige vers un nouvel objectif "Sortie"

J'avoue que je ne connais pas enormément le navmesh agent =/ ni trop les listes...
Du coup c'est pour ça que je suis un peu perdu....

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 18:42
par Max
Darym a écrit :
31 Mai 2019 18:17
IA check les objectifs existant et les place dans une liste
IA se dirige vers Objectif le plus proche (A)
IA Atteint Objectif A
IA Retire Objectif A de sa liste et se dirige vers le nouvel Objectif le plus proche (B)
IA Atteint Objectif B
IA Retire Objectif B de sa liste et se dirige vers le nouvel Objectif le plus proche (C)
ça ok, là la logique est plutôt clair et classique.Le soucis je pense est dans la mise en œuvre niveau code.
Là où je tique un peu, c'est dans ta façon de chercher à savoir quand ton IA atteint un objectif.
Perso, pour tester si mon IA atteint le target désigné, je pars sur une simple comparaison de la position courante de l'IA et la position du target. Si cette distance les séparant descend sous une certaine valeur, alors on peut considérer le target atteint, on le supprime de la liste des objectifs, puis on assigne le target (objectif) suivant à l'IA.
Une autre technique pour détecter un but sur un target, est celle qui consiste à passer par des triggers sur chaque objectif. Quand l'IA rentre dedans, alors objectif est atteint, on passe au suivant.

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 18:48
par Darym
La actuellement je fais fonctionner par un trigger, ce trigger declenche le retrait de l'objectif ("closest" dans mon code) sauf que....
Comme ma liste est publique je m'en rend compte trés rapidement, le retrait de closest retire TOUS les éléments de ma liste, et du coup mon ia n'avance plus...
L'idée est assez simple (enfin je pense) mais je pêche complètement dans son exécution...
Avez-vous une idée pour que ça ne retire qu'un seul élément de la liste?

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 19:05
par Max
Si on reprend ton code, dans la méthode ChangeTarget(), tu "Remove" les go dont la distance courante est inférieure à la valeur distance... qui est elle égale à l'infini. Donc forcément, tout tes targets sont supprimés...

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 21:01
par Darym
Bon sang que je suis ***...
j'ai juste mis un float égal à 2.0 et ça a fonctionné XD
Mille merci! ça m'a vraiment aidé!
Merci pour ton aide et t patience!!!!

Re: [DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 21:10
par Max
Pas de soucis, passe ton sujet en [RESOLU] et se sera top ;)

Re: [Résolu][DB - AL] Faire une IA qui va d'un point à un autre sans destruction

Publié : 31 Mai 2019 21:42
par Darym
Fait. ^^ Merci encore!