Suivre chemin

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6449
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: Suivre chemin

Message par boubouk50 » 29 Juil 2024 14:14

Je n'ai malheureusement pas trop de temps à te consacrer même si le sujet m'intéresse.
De ce que je vois, pour moi, le principal problème se situe dans le calcul des 5°, il est approximatif et ne gère pas toutes les conditions.
Avec le LineRenderer, si le joueur revient sur ses pas, alors le point à supprimer est le dernier. Il faut donc trouver un moyen de savoir si le joueur à dépasser ce (ou ces!!) points.
Par exemple, avec la position précédente de la bille et celle en cours, tu pourrais déterminer si le dernier point est entre les deux. Si oui, alors recommencer avec le point suivant (au cas où il y aurait d'autres points si le pointeur est allé très vite).
Une autre possibilité serait de créer des points avec collider pour que la bille rentre en trigger avec, pour signaler qu'un point est atteint donc il faut l'enlever (ou le mettre si tu prévois les futurs chemins).
C'est vraiment une question d'algorithme à ce niveau.
Avant de coder quoique ce soit, il faut que les objectifs de ta bille soient clairs et que tu sois sûr que la solution que tu vas mettre en place soit fonctionnelle et réponde à tous ces objectifs.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 29 Juil 2024 18:08

Merci Boubouk,
Je suis en train d'essayer de mettre en place ton autre solution avec les triggers.
Ca me semble plus facile à gérer.
Je voudrais tout de même savoir s'il y a moyen de limiter la course de la bille si le joueur fait n'importe quoi.
Je posterai, sûrement demain, les modifications que j'aurai mises en place.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6449
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: Suivre chemin

Message par boubouk50 » 30 Juil 2024 09:21

Dans le code que je t'ai donné, il y a une notion de distance entre le curseur et la bille. Si elle est dépassée, le drag est arrêté.
Tu peux aussi le faire avec un trigger rond sur la bille pour le simuler plutôt que le calculer.
Aussi, tu pourrais avoir un seuil de pixels de déplacement de la souris. Si la souris a fait plus de 100px sur un Update, alors elle va trop vite, donc le drag est coupé.
Ces deux conditions cadreraient le jeu pour que le joueur soit plus précis et lent dans ces déplacements, par exemple.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 30 Juil 2024 12:33

J'ai diminué la valeur distance entre le curseur et la bille, et si cette distance est dépassée je désactive isSelected ainsi ça oblige le joueur à réactiver la bille pour éviter un sursaut quand le curseur se rapproche.
Ca limite une partie du problème.
Si j'ai bien compris ta solution ce serait de mettre un trigger sur la bille avec un diamètre un peu plus grand et de provoquer le déplacement que si la souris reste dans ce trigger ?
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6449
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: Suivre chemin

Message par boubouk50 » 30 Juil 2024 12:53

Oui, tu peux créer un trigger dédié à ça sur la bille (plutôt son enfant ou parent).
Tu as des fonctions comme OnMouseEnter, OnMouseOver, OnMouseExit déjà prêtes qui te permettent de facilement gérer les conditions d'interaction entre la souris et le collider.
Tu as aussi le component Event Trigger, qui le fait directement, sans code, où tu peux décider ce que déclenche les interactions simples : OnMouseEnter, Exit, Stay, OnDrag, Begin, End, etc.
Ça fera la même chose que calculer la distance. L'avantage, c'est que tu le règles visuellement dans Unity en changeant simplement le radius du collider.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 30 Juil 2024 13:51

Voilà ce que j'ai créé grâce à tes conseils

Package

Je t'envoie le package pour que tu puisses avoir accès à l'ensemble du projet, qui n'est d'ailleurs qu'un petit démarrage.
Tu peux constater qu'en cours de déplacement d'une bille le chemin arrive à laisser des trous. Je voudrais limiter la vitesse de déplacement afin d'éviter ces trous.

De plus je voudrais arriver à bloquer le déplacement de la bille si elle entre dans une case colorée sauf si elle est en cours d'un retour. J'avais déjà vue ça dans un autre script ou j'avais mis une valeur sens et exSens qui me permettait de voir le sens de la rotation et si le sens était inversé, on effaçait le chemin parcouru. Là j'avoue ne pas savoir comment déterminer le sens du déplacement.

Tes conseils seraient hyper bien venus
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6449
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: Suivre chemin

Message par boubouk50 » 30 Juil 2024 14:29

Ok. J'essaierai de regarder ça un de ces soirs. (pas ce soir en tout cas)
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 30 Juil 2024 15:08

Il faut savoir qu'il y a plusieurs billes car dans certains défis on peut commander différentes billes et les autres se déplacent comme dans un miroir.

Chaque bille doit être sensible aux chemins déjà empruntés et à certains objets (obstacle ou bonus) qu'il faut éviter ou récupérer en cours de chemin. Tout ça fera l'objet d'autres questions quand j'aurai enfin réussi à gérer les déplacements comme il faut.

A savoir aussi que la grille présentée n'est qu'un exemple et les autres seront pour la plupart différentes et sûrement plus grandes

merci Boubouk
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 31 Juil 2024 16:05

J'ai modifié un peu le script "Defi" pour essayer d'effacer les cases quand on revient en arrière mais j'avoue que je n'y arrive pas vraiment. (ce doit être l'âge :pleur4: ).
Quand on va très lentement des fois ça marche. sinon ça ne s'efface pas.

Voilà le script modifié :

Code : Tout sélectionner

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Defi : MonoBehaviour
{
    [SerializeField] private Transform[] centres = null;

    [SerializeField] private Transform centre = null;
    [SerializeField] private Transform bille;
    [SerializeField] private Vector3 mousePos;

    private void RechercheCentre()
    {
        mousePos = CalculePositionSouris();
        float distance = float.PositiveInfinity;
        Transform newCenter = centres[0];

        // Calcul du centre le plus proche de la souris -> On pourrait totalement mettre un
        // collider carré sur chaque centre pour savoir directement quel objet est sous la souris
        foreach (Transform rend in centres)
        {
            // Calcul de la distance avec chaque centre
            float dist = (rend.position - mousePos).sqrMagnitude;
            // Si la nouvelle distance est plus courte, on prend le nouveau centre
            if (dist < distance)
            {
                newCenter = rend;
                distance = dist;
            }
        }

        // Si le centre le plus proche est different
        if (centre != newCenter)
        {
            centre = newCenter;
        }
    }

    //calcule la position de la souris
    private Vector3 CalculePositionSouris()
    {
        Vector3 mouseScreenPosition = Input.mousePosition;
        float distanceToCamera = Vector3.Distance(centre.position, Camera.main.transform.position);
        Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(mouseScreenPosition.x, mouseScreenPosition.y, distanceToCamera));
        pos.z = transform.position.z;
        return pos;
    }

    private void Start()
    {
        foreach (GameObject item in GameObject.FindGameObjectsWithTag("Path").ToList())
        {
            item.transform.Color(Color.clear);
        }
        foreach (GameObject item in GameObject.FindGameObjectsWithTag("Croix").ToList())
        {
            item.transform.Color(Color.clear);
        }
    }

    internal void DragBille(Transform b)
    {
        if (bille == null || bille != b)
        {
            bille = b;
            RechercheCentre();
        }
        if (Input.GetMouseButton(0))
        {
            mousePos = CalculePositionSouris();
            Vector3 dir = (mousePos - centre.transform.position).normalized;
            Vector3 position = centre.transform.position + dir;
            position.z = bille.position.z;

            if (ControleMouvementPossible())
            bille.position = position;
        }

    }

    public bool retour;
    public Transform newCase;
    public Transform curCase;
    public Transform exCase;
    private bool ControleMouvementPossible()
    {
        if (curCase != null)
        {
            //si la case actuelle est vide
            if (curCase.Color() == Color.clear)
            {
                curCase.Color(bille.Color());
            }
        }

        if (newCase != null && newCase != curCase)
        {
            //si la case suivante est vide
            if (newCase.Color() == Color.clear)
            {
                //la dernière case occupée est la courante
                exCase = curCase;
                //si mode retour: le retour est terminé
                retour = false;
                //on peut déplacer
                return true;
            }
            //si la case suivante est colorée
            else
            {
                //si on revient sur l'ancienne case
                if (exCase == newCase)
                {
                    //on active le retour
                    retour = true;
                }
                //si le retour est activé
                if (retour)
                {
                    //on efface la case courante
                    curCase.Color(Color.clear);
                    //et on autorise le déplacement
                    return true;
                }
                //si le retour n'est pas activé
                else
                {
                    newCase = null;
                    //on refuse le déplacement
                    return false;
                }
            }
        }

        return true;
    }

    Transform exPath;
    internal void EnterPath(Transform path, Transform objet)
    {
        if (centre == null || bille == null) return;
        if (objet == bille)
        {
            if (path.tag == "Path" || path.tag == "Croix")
            {
                if (path != exPath)
                {
                    newCase = path;
                }
            }
        }
    }

    internal void StayPath(Transform path, Transform objet)
    {
        if (centre == null || bille == null) return;
        if (objet == bille)
        {
            if (path.tag == "Croix")
            {
                RechercheCentre();
            }
            if (path.tag == "Path" || path.tag == "Croix")
            {
                if (path != exPath && curCase != path)
                {
                    if (bille.position.Environ(path.position, 0.05f))
                    {
                        curCase = path;
                        exPath = path;
                    }
                }
            }
        }
    }
}

La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 749
Inscription : 18 Mars 2017 19:39

Re: Suivre chemin

Message par EmileF » 01 Août 2024 14:21

Il y en a qui bossent ici. :langue2:

J'ai repris tout mon projet à ma sauce, en fait, c'est celle que je comprends le mieux.

Le seul soucis qui m'ennuie vraiment c'est que ma bille se bloque au lieu d'effacer et pas moyen de la débloquer.

Sinon, la bille suit le curseur dès que celui-ci se déplace, Il trace le chemin avec le système LineRenderer, Il efface en cas de retour et s'arrête si elle rencontre un chemin déjà tracé.

Elle change de direction aux carrefours en suivant le curseur.

Je pense être arrivé à un résultat acceptable sauf le cas ou dans certains carrefours elle se bloque au lieu de continuer à effacer.

Voici
le package

Salut Boubouk et j'espère que tout va bien. :hello:

Si quelqu'un à des idées pour améliorer le truc ses conseils seront les bienvenus.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Répondre

Revenir vers « Scripting »