[RESOLU] [DB-AL] Faire avancer un objet en fonction de sa rotation (une flèche)

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Beogus
Messages : 13
Inscription : 29 Mars 2021 17:42

[RESOLU] [DB-AL] Faire avancer un objet en fonction de sa rotation (une flèche)

Message par Beogus » 28 Jan 2024 20:08

Bonjour,

pour poser le contexte, je réalise un jeu de style Rogue-like (dans le genre Vampire survivors)
donc un personnage au centre qui modifie son orientation en fonction du déplacement de la souris autour de lui.

Mon problème peut paraitre simple, mais je ne trouve pas la solution :
Je souhaite faire tirer une flèche à mon personnage. j'instancie donc la flèche au niveau de l'arc du personnage à l'aide d'un AnimEvent au moment où il bande son arc. cette flèche est orientée dans la même direction que celle du personnage.

Code : Tout sélectionner

void TirerFleche()
{
    Vector3 offset = new Vector3(0f, 0f, 0.0002f); // j'ajoute un léger décalage

    // je récupère la rotation de mon personnage (le script se trouve sur lui)
    float rotationYJoueur = transform.rotation.eulerAngles.y;

    Quaternion rotation = Quaternion.Euler(0f, rotationYJoueur, 0f);

    // j'instancie la flèche avec la position et rotation locales ajustées
    GameObject nouvelleFleche = Instantiate(flecheProjo, player.arme.transform.position + offset, rotation);
    }
    
ici tout va bien, la flèche s'oriente bien sur l'orientation du personnage, le problème vient ensuite :
J'ai donc un script sur la flèche pour gérer son déplacement et là ça coince :

Code : Tout sélectionner

void Update()
{
    DirectionFleche();
        distanceParcourue += forceDeTir * Time.deltaTime;
    //  si la flèche a parcouru la distance de destruction je la détruit
    if (distanceParcourue >= distanceDeDestruction)
    {
        DetruireFleche(); 
}

public void DirectionFleche()
{
    directionDeTir = transform.forward;
    directionDeTir.Normalize();
    
    transform.Translate(directionDeTir * forceDeTir * Time.deltaTime);
    // ici forceDeTir est une variable float
}

}
Donc normalement, de ce que je sais (ou crois savoir?) la flèche est censé aller vers l'avant de façon locale, donc vers son propre axe Z . Donc lorsqu'il pointe vers l'ouest, elle devrait aller vers l'ouest. mais ce n'est pas le cas, lors de ce schéma, elle va vers le sud. Voici ce que j'ai pu comprendre avec mes différents tests :

- quand l'axe Z local est orienté vers l'axe X globale, la flèche va vers l'axe X local.
- quand l'axe Z local est orienté vers l'axe - X global, la flèche va vers le -X local.
- et ainsi de suite, si il est orienté vers le sud-ouest, elle ira vers le sud-est.
-Le seul cas où ça fonctionne bien c'est lorsque les deux axes sont alignés (donc le Z vers le nord)

Un peu comme si (prenons l'exemple de la flèche qui pointe vers l'ouest, donc X global) il prenait l'axe Z local, le calquait sur l'orientation Globale donc le x Global devient le Z local, puis qu'il recalqué ça sur la direction local, comme l'axe Z est devenu l'axe X alors forward suis l'axe X local.

voici un petit screen pour illustrer l'exemple :
Image


Je ne sais pas si j'ai réussi à être clair, j'espère que mes tentatives d'explications et hypothèses ne vous ont pas trop embrouillé.

Merci d'avance pour votre aide.
Dernière édition par Beogus le 29 Jan 2024 17:23, édité 1 fois.

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

Re: [DB-AL] Faire avancer un objet en fonction de sa rotation (une flèche)

Message par boubouk50 » 29 Jan 2024 10:21

Salut,

Tu entremêles axe local et global et ça fait des chocapics. Pour ne pas se tromper, il faut s'assurer que le repère reste le même au cours des calculs.

Code : Tout sélectionner

directionDeTir = transform.forward;
Ici, tu récupères le vecteur Z dans le repère World. En local, Z vaut (0, 0, 1).

Code : Tout sélectionner

transform.Translate(directionDeTir * forceDeTir * Time.deltaTime);
Ici, tu fais une transformation dans le repère local (Doc TranslaterelativeTo vaut Self par défaut).

Donc soit, tu utilises le repère local pour ta directionDeTir, soit tu utilises le repère global pour la transformation (Space.World).
"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

Beogus
Messages : 13
Inscription : 29 Mars 2021 17:42

Re: [DB-AL] Faire avancer un objet en fonction de sa rotation (une flèche)

Message par Beogus » 29 Jan 2024 17:22

Ha Merci beaucoup, effectivement, ça marche beaucoup mieux !

au fait je partais du principe que transform.forward prenait en compte l'axe Z en fonction de la rotation local de l'objet, donc son axe Z local.

et donc qu'il n'y avait pas besoin d'un Space.World puisque je voulais qu'elle se déplace le long de cet axe locale donc pour moi les deux données étaient des données locales et tout était bon.

mais du coups il fallait donc que je fasse soit :

Code : Tout sélectionner

transform.Translate(Vector3.forward * forceDeTir * Time.deltaTime);
//avec le Space.Self optionnel car par défaut
Soit :

Code : Tout sélectionner

transform.Translate(transform.forward * forceDeTir * Time.deltaTime, Space.World);
Je pense avoir bien compris maintenant, merci encore, j'ai mis le sujet en résolu.

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

Re: [DB-AL] Faire avancer un objet en fonction de sa rotation (une flèche)

Message par boubouk50 » 29 Jan 2024 17:39

Beogus a écrit :
29 Jan 2024 17:22
Ha Merci beaucoup, effectivement, ça marche beaucoup mieux !

au fait je partais du principe que transform.forward prenait en compte l'axe Z en fonction de la rotation local de l'objet, donc son axe Z local.

et donc qu'il n'y avait pas besoin d'un Space.World puisque je voulais qu'elle se déplace le long de cet axe locale donc pour moi les deux données étaient des données locales et tout était bon.

mais du coups il fallait donc que je fasse soit :

Code : Tout sélectionner

transform.Translate(Vector3.forward * forceDeTir * Time.deltaTime);
//avec le Space.Self optionnel car par défaut
Soit :

Code : Tout sélectionner

transform.Translate(transform.forward * forceDeTir * Time.deltaTime, Space.World);
Je pense avoir bien compris maintenant, merci encore, j'ai mis le sujet en résolu.
:| Un membre qui détaille la solution et qui passe un sujet en résolu ! :amen:
"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

Répondre

Revenir vers « (C#) CSharp »