[RESOLU]C# Donner la direction d'un objet

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

[RESOLU]C# Donner la direction d'un objet

Message par Bilu » 26 Juil 2020 18:56

Bonjour,

Dans mon jeu, mon personnage peut bouger dans toutes les directions dans le plan xy. À certain moment, des objets apparaissent sur la map et j'aimerai avoir une indication de direction que doit prendre mon personnage pour atteindre cet objet.

J'aimerai donc que cet indicateur puisse tourner autour de mon personnage tout en restant en bordure d'écran (visible donc de la caméra principal). Je n'ai rien trouvé de fonctionnel sur internet pour m'aider à faire roter un objet (l'indicateur de direction) par rapport à la position d'un autre objet (joueur).

Pourriez-vous m'aider ?

Bien à vous,

Bilu
Dernière édition par Bilu le 14 Sep 2020 14:24, édité 3 fois.

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: C# Indiquer une direction

Message par Max » 27 Juil 2020 12:03

Hello,
Bilu a écrit :
26 Juil 2020 18:56
J'aimerai donc que cet indicateur puisse tourner autour de mon personnage tout en restant en bordure d'écran (visible donc de la caméra principal).
Perso, je comprend pas trop le "puisse tourner autour de mon personnage tout en restant en bordure d'écran". Tu as un screen pour mieux comprendre ?
Si tu penses à un truc du genre réticule orientable à la base de ton player, regarde par exemple du coté des Projectors.


Bilu a écrit :
26 Juil 2020 18:56
Je n'ai rien trouvé de fonctionnel sur internet pour m'aider à faire roter un objet
une piste: Image
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

Re: C# Indiquer une direction

Message par Bilu » 27 Juil 2020 18:51

Bonjour Max
Max a écrit :
27 Juil 2020 12:03
...
Bilu a écrit :
26 Juil 2020 18:56
Je n'ai rien trouvé de fonctionnel sur internet pour m'aider à faire roter un objet
une piste: Image
Hahaha :lol:

https://www.youtube.com/watch?v=CuKrEC0jusM

Sur cette vidéo à 8 secondes, il y a un missiles qui arrive par haut et un indicateur rouge montre au joueur par où arrivent ce missile. A partir de 6 secondes il y a un indicateur bleu qui signale au joueur qu'il y a quelque chose à récupérer.
Ces deux indicateurs restent en bordures d'écrans (donc toujours visible) pour aider le joueur. On dirait que ça pivote autour du joueur tout en restant en bordure d'écran.
Est-ce plus clair ?

Bien à toi,

Bilu

Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

Re: C# Indiquer une direction

Message par Bilu » 04 Août 2020 17:28

Bonjour,

Je reviens vers vous car j'ai toujours pas trouvé la solution à mon problème.

Donc voici une image pour illustrer mon soucis :
Image

Quand l'objet en jaune en haut à droite sort de la vision de la caméra (carré blanc autour du joueur en rose) je voudrai que le petit objet jaune sert d'indication pour donner la direction que doit prendre le joueur pour le retrouver.

Pour ça j'ai utilisé le code suivant :

Code : Tout sélectionner

	dir = money.position - player.position;
        dirDuplicate = dir;
        //dir.Normalize();

        float alpha = (float)Math.Atan2(dir.x, dir.y)  ;



        Vector3 pos = transform.position;      
        
       if (dir.x > camWidth/2 && dir.y < camHeight / 2)
        {
            dirDuplicate.x = camWidth/2 - camWidth/100*1;
            dirDuplicate.y = dirDuplicate.x * (float)Math.Tan(alpha);
        }

       if (dir.y > camHeight/2 && dir.x < camWidth / 2)
        {
            dirDuplicate.y = camHeight / 2 - camHeight / 100 * 1;
            dirDuplicate.x = dirDuplicate.y / (float)Math.Tan(alpha);
        }

        if (dir.x > camWidth / 2 && dir.y > camHeight / 2)
        {
            dirDuplicate.x = camWidth / 2 - camWidth / 100 * 1;
            dirDuplicate.y = dirDuplicate.x * (float)Math.Tan(alpha);
        }


        if (dirDuplicate.x < camWidth / 2 && dirDuplicate.y < camHeight / 2)
        {
            Die();

        }

        
        transform.position = player.position + dirDuplicate;
Mais ça ne marche pas.
Premièrement, quand je fait :
transform.position = player.position + dir;

L'indicateur se trouve pile poil sur l'objet jaune donc la direction est bonne. Mais l'indicateur n'est pas dans la vision de la caméra donc j'utilise les Atan2 alpha, Tan ... pour le forcer à rester dans la vision de la caméra mais comme vous pouvez le constater l'indicateur est tjs hors de la cam mais en plus si vous tracer une ligne entre le joueur et la money, l'indicateur n'est pas dessus donc la direction n'est plus bonne.

Est ce que vous pourriez m'aider s'il vous plaît ?

Bien à vous,

Bilu

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: C# Indiquer une direction

Message par Max » 04 Août 2020 19:01

Bonsoir,

perso, en terme d'approche, je partirais sur 4 colliders enfant du player, formant un rectangle lié à la dimension de l'écran.
Et pour le reste, super simple: tu fais un Physics2D.Raycast() entre ton player et l'eni, le point de contact avec le cadre collider représentant la position où doit se trouver ton indicateur.

Image
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

Re: C# Indiquer une direction

Message par Bilu » 04 Août 2020 21:26

Je vais regarder à ca merci :)

Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

Re: C# Indiquer une direction

Message par Bilu » 31 Août 2020 08:08

Bonjour,

J'ai enfin réussi à faire ce que je voulais.
Il suffit de faire un peu de mathématique :)
J'ai également décidé de changer le nom du thread pour que cela soit plus clair
Pour ceux que cela intéresse, voici le code ;)

J'ai un script qui fait spawn une flèche (qui pointe vers l'objet à récupérer) quand l'objet à pointer est hors de l'écran (hors de la vue de mon personnage) et est détruit quand l'objet entre dans l'écran. Et le script ci-dessous gère la flèche de direction

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Media;
using System.Security.Cryptography;
using UnityEngine;
using System;

public class MoneyShower : MonoBehaviour
{
    Transform player;
    Transform money;

    float alpha;
    float alphaDuplicate;
    float alphaLimite;

    Vector3 dir;
    Vector3 dirDuplicate;

    float camWidth;
    float camHeight;

    Camera cam;

    // Start is called before the first frame update
    void Start()
    {
        cam = Camera.main;
        alphaLimite = (float)Math.Atan(camHeight / 2 / (camWidth / 2));
    }

    // Update is called once per frame
    void Update()
    {

        camHeight = 2f * cam.orthographicSize;
        camWidth = camHeight * cam.aspect;

        alphaLimite = (float)Math.Atan(camHeight / 2 / (camWidth / 2));

        if (player == null)
        {
            GameObject go = GameObject.Find("shipPlayer_1");

            if (go != null)
            {
                player = go.transform;

            }
        }

        if (money == null)
        {
            GameObject go2 = GameObject.Find("money");

            if (go2 != null)
            {
                money = go2.transform;

            }
        }

        dir = money.position - player.position;
        dirDuplicate = dir;
        //dir.Normalize();

        alpha = (float)Math.Atan(dir.y/dir.x);

        alphaDuplicate = Math.Abs(alpha);



        Vector3 pos = transform.position;

        if (dir.x >= 0 && dir.y >=0 )
        {
            if (alphaDuplicate <= alphaLimite )
            {
                pos.x = camWidth / 2;
                pos.y = camWidth / 2 * (float)Math.Tan(alpha);

            }
            else
            {
                pos.y = camHeight / 2;
                pos.x = camHeight / 2 / (float)Math.Tan(alpha);
            }
        }

        else if (dir.x <= 0 && dir.y >= 0)
        {
            if (alphaDuplicate <= alphaLimite)
            {
                pos.x = -camWidth / 2 + (float)0.5;
                pos.y = -camWidth / 2 * (float)Math.Tan(alpha);

            }
            else
            {
                pos.y = camHeight / 2;
                pos.x = camHeight / 2 / (float)Math.Tan(alpha) ;
            }

        }
        else if (dir.x >= 0 && dir.y <= 0)

        {
            if (alphaDuplicate <= alphaLimite)
            {
                pos.x = camWidth / 2;
                pos.y = camWidth / 2 * (float)Math.Tan(alpha);

            }
            else
            {
                pos.y = -camHeight / 2 + (float)0.5;
                pos.x = -camHeight / 2 / (float)Math.Tan(alpha) ;
            }

        }
        if (dir.x <= 0 && dir.y <= 0)
        {
            if (alphaDuplicate <= alphaLimite)
            {
                pos.x = -camWidth / 2+ (float)0.5;
                pos.y = -camWidth / 2 * (float)Math.Tan(alpha);

            }
            else
            {
                pos.y = -camHeight / 2 + (float)0.5;
                pos.x = camHeight / 2 / (- (float)Math.Tan(alpha));
            }
        }



        /*if (dir.x > camWidth/2 && dir.y < camHeight / 2)
         {
             dirDuplicate.x = camWidth/2 - camWidth/100*1;
             dirDuplicate.y = dirDuplicate.x * (float)Math.Tan(alpha);
         }

        if (dir.y > camHeight/2 && dir.x < camWidth / 2)
         {
             dirDuplicate.y = camHeight / 2 - camHeight / 100 * 1;
             dirDuplicate.x = dirDuplicate.y / (float)Math.Tan(alpha);
         }

         if (dir.x > camWidth / 2 && dir.y > camHeight / 2)
         {
             dirDuplicate.x = camWidth / 2 - camWidth / 100 * 1;
             dirDuplicate.y = dirDuplicate.x * (float)Math.Tan(alpha);
         }*/


        if (Math.Abs(dirDuplicate.x) < camWidth / 2 && Math.Abs(dirDuplicate.y) < camHeight / 2)
        {
            Die();

        }

        
        transform.position =  player.position + pos;

    }

    void Die()
    {
        Destroy(gameObject);
       
    }

    /*private void OnGUI()
    {

        GUI.Label(new Rect(0, 150, 150, 100), "alpha: " + alpha);
        GUI.Label(new Rect(0, 175, 150, 100), "alphaLimite : " + alphaLimite);
        GUI.Label(new Rect(0, 200, 150, 100), "dirNotNorm.x : " + dirDuplicate.x);
        GUI.Label(new Rect(0, 225, 150, 100), "dirNotNorm.y : " + dirDuplicate.y);
        GUI.Label(new Rect(0, 250, 150, 100), "dirNotNorm.y : " + dir.x);
        GUI.Label(new Rect(0, 275, 150, 100), "dirNotNorm.y : " + dir.y);

    }*/
}
Cependant, il me reste un soucis.
Avec ce code, cela fonctionne très bien quand un seul objet est à pointer.
Mais si j'ai plusieurs objets, non. Par exemple, Si je dois donner la direction de plusieurs ennemis ?
Ce code ne fonctionne pas dans ce cas. Il y a bien plusieurs indicateurs de direction mais ils indiquent tous le même ennemi.
Quoi m'a donné un début de solution mais je ne sais pas comment la réaliser :
Il faut que mon objet flèche(indicateur) soit parenté aux objets qui peuvent être fléchés et cacher son image que je fais ensuite réapparaître quand l'objet sort de l'écran (Donc plus de spawner et la partie, cacher et faire réapparaître, pas de soucis). Il faut que ma flèche se réfère à l'instance de l'objet au quel elle est parentée. Cette deuxième partie par contre, je ne sais pas du tout comment faire cela ?

Pourriez-vous m'aider ?

Bien à vous,

Bilu

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: C# Indiquer une direction

Message par Max » 31 Août 2020 20:31

Bilu a écrit :
31 Août 2020 08:08
Il faut que ma flèche se réfère à l'instance de l'objet au quel elle est parentée. Cette deuxième partie par contre, je ne sais pas du tout comment faire cela ?
Quand tu instancies ton ENI, il faut lui passer la référence de la flèche qui lui est attribuée.
Pour parenter un objet à un autre, regarde du coté de Transform;parent.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Bilu
Messages : 91
Inscription : 20 Nov 2019 09:24

Re: C# Donner la direction d'un objet

Message par Bilu » 03 Sep 2020 17:23

Bonjour,

Merci Max, ça fonctionne !! :amen:

Par contre, il y a un truc bizarre :
L'objet enfant voit sa rotation suivant les axe X et Y qui s'affole ainsi que la valeur de Scale de X,Y et Z.
Hors, rien, aucune ligne de code, n'est fait pour que ces valeurs changent que ce soit pour l'objet enfant ou l'objet parent.
C'est un jeu en 2D donc je ne vois ce qui agit sur la rotation suivant X et Y et surtout que rien n'est censé influencer les valeurs de scale.
Auriez vous une idée de pourquoi ces valeurs changent et ne reste pas à zéro (ou du moins une valeur fixe) ? Pourquoi ces valeurs changent tout le temps alors qu'aucune ligne de code ne le demande ?

Bilu

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: C# Donner la direction d'un objet

Message par Max » 03 Sep 2020 17:57

Bonjour,

tu n'as pas de composants physique sur certains éléments, genre RigidBody ?
(bien que je ne vois pas directement le rapport avec le scale)
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Répondre

Revenir vers « Scripting »