IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Unity Discussion :

centrer une grille 6x10, 5x12, 4x15 ou plus


Sujet :

Unity

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 170
    Points : 0
    Points
    0
    Par défaut centrer une grille 6x10, 5x12, 4x15 ou plus
    Bonjour à tous,

    J'ai crée une grille (lignes et colonnes), contitués de plusieurs petits planes (gridCellPrefab de tailles 0.1f).
    Le code se trouve ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     private void CreateGrid()
        {
            for (int i = 0; i < Lignes; i++)
                for (int j = 0; j < Colonnes; j++)
                {
                    Vector3 worldPosition = new Vector3(i, 0f, j);  
                    obj = Instantiate(gridCellPrefab, worldPosition, Quaternion.identity);
        }




    Comme je l'ai déjà dit, je cherche à centrer ma grille dans la scène.
    Cependant ma grille peut être de longueur et de largeur 6x10, 5x15, 4x20 ou bien 3*20.
    C'est pour cela que j'aimerais centrer ma grille.

    Voilà la position de ma camera.


    Merci pour votre aide,

    A+

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 975
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 975
    Points : 221 711
    Points
    221 711
    Billets dans le blog
    131
    Par défaut
    Bonjour,

    Ultra simple (avec un peu de mathématique). Dans ce genre de problème il faut absolument prendre une feuille et un crayon et visualiser le problème (le dessiner) Il faut s'assurer que le carré du milieu est... au milieu (et chez nous, le "milieu" c'est 0, 0, 0). Cela veut dire que pour une grille de 4 x 4, le milieu, c'est le point entre les second et troisième carré, Dans une grille de 8 x 8, c'est entre le quatrième et le cinquième carré.
    On remarque un pattern.
    Mais on peut aussi prendre le problème un peu différemment, et se dire : tiens, ma grille doit être décalée après création. De combien ?
    Simplement de la moitié de sa taille (c'est toujours comme ça que l'on centre). Alors, ici, plusieurs solutions :
    • vous créez la grille et vous recalez par la suite ;
    • vous créez la grille décalée (au lieu de démarrer de 0, vous démarrez de -taille / 2).


    En exercice bonus, centrez une grille de taille imper

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 170
    Points : 0
    Points
    0
    Par défaut
    Salut à tous,

    Voici le code de la grille à centrer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    private void CreateGrid()
        {
            for (int i = 0; i < Lignes; i++)
                for (int j = 0; j < Colonnes; j++)
                {
                    Vector3 worldPosition = new Vector3(i - 6f, 0f, j);  
                    obj = Instantiate(gridCellPrefab, worldPosition, Quaternion.identity);
        }
    J'ai remarqué que si je soustrais 6f à la variable i (variable des lignes de la boucle), la grille 6x10 se centre à peu prés bien dans la scène (horizontalement).
    Si je soustrais 5f à la variable i, la grille 5x12 se centre bien dans la scène (un peu moins bien mais quand même).
    Si je soustrais 7f à la variable i, la grille 4x15 se centre à peu près dans la scène.
    Si je soustrais 9f à la variable i, la grille 3x20 se centre à peu près dans la scène.
    Si je soustrais 6f à la variable i, la grille 8x8 se centre à peu près dans la scène.
    Si je soustrais 6f à la variable i, la grille 5x5 se centre à peu près dans la scène.
    Si je soustrais 3f à la variable i, la grille 3x3 se centre à peu près dans la scène.

    Comme vous pouvez le voir les valeurs sont approximatives, cela varie de 9f à 3f.
    On pourrait croire que la valeur à soustraire est égale à la valeur de la ligne.
    Il peut y avoir des nombres à virgules histoire d'être plus précis dans le centrage dans la scène.


    J'ai besoin de placer une centaine de grille donc j'ai besoin de code.

    Si quelqu'un pouvait m'aider à trouver la formule.
    Je dis bien il peut y avoir des nombres à virgule (tout cela reste relatif entre le nombre en float à soustraire et la taille de la grille)

    Merci pour votre aide,

    A+

  4. #4
    Membre émérite
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 654
    Points : 2 335
    Points
    2 335
    Par défaut
    Bonjour,

    Je ne vais faire que synthétiser tout ce qui t'as été proposé, ici comme ailleurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            Vector3 gridCenter = new Vector3(Lignes / 2F, 0f, Colonnes / 2F); // On calcule le centre de la grille brut
            Vector3 cellCenter = new Vector3(1 / 2F, 0, 1 / 2F); // On calcule le centre d'une cellule
     
            for (int i = 0; i < Lignes; i++)
            {
                for (int j = 0; j < Colonnes; j++)
                {
                    Vector3 worldPosition = new Vector3(i, 0f, j) - gridCenter + cellCenter; // On soustrait le centre pour avoir le bon offset et on ajoute le centre d'une cellule car on part du coin haut-gauche
     
                    var obj = Instantiate(cellPrefab, worldPosition, Quaternion.identity, transform);
                }
            }
    Evidemment, vu que tu as choisi la taille de tes planes pour que 1 unité = 1 cellule, les calculs sont simples, mais s'il fallait changer cela, il faudra revoir un peu tout, mais ça ne serait pas très compliqué.




    En bonus, je te mets aussi une méthode qui te permet aussi de changer la manière de centrer, et qui peut servir pour des projets futurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public static Bounds GetTotalBounds(GameObject gameObject)
        {
            Bounds bounds = new Bounds(Vector3.zero, Vector3.one);
     
            Renderer[] meshes = gameObject.GetComponentsInChildren<Renderer>();
     
            foreach (var mesh in meshes)
            {
                bounds.Encapsulate(mesh.bounds);
            }
     
            return bounds;
        }
    Une fois que tu as créer chaque cellule ancré a un parent, il te suffirait de calculer la taille de la grille, et de simplement soustraire la moitié à sa position et voilà.

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 170
    Points : 0
    Points
    0
    Par défaut
    Bonjour à tous,

    Merci pour ton aide précieuse,
    qu'entends-tu par

    Une fois que tu as créer chaque cellule ancré a un parent, il te suffirait de calculer la taille de la grille, et de simplement soustraire la moitié à sa position et voilà.
    Est-ce que gameObject est un plan (de taille 1 ou moins)?

    Que renvoie le code :
    Excusez moi pour ces questions mais je suis encore débutant, et j'ai une grande soif d'apprendre le logiciel Unity.

    Merci pour votre aide,

    A+

  6. #6
    Membre émérite
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 654
    Points : 2 335
    Points
    2 335
    Par défaut
    Citation Envoyé par julius1983 Voir le message
    Bonjour à tous,
    Est-ce que gameObject est un plan (de taille 1 ou moins)?
    Le paramètre gameObject est n'importe quel objet en 3D dont tu veux les bounds, c'est tout. Tant qu'il y a un MeshRenderer attaché a cet objet, ça marchera.

    Par contre cette méthode ce n'est que du bonus, ma première solution marche très bien et fonctionne avec ton code, est-ce que tu as réussi à le faire marcher du coup ?

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 170
    Points : 0
    Points
    0
    Par défaut
    Salut à tous,

    J'ai rentré le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     void Start()
        {
            CreateGrid();
        }
     
      private void CreateGrid()
         {
                Vector3 gridCenter = new Vector3(Lignes / 2f, 0f, Colonnes / 2f); // On calcule le centre de la grille brut
             Vector3 cellCenter = new Vector3(1 / 2f, 0, 1 / 2f); // On calcule le centre d'une cellule
     
             for (int i = 0; i < Lignes; i++)
             {
                 for (int j = 0; j < Colonnes; j++)
                 {
                     Vector3 worldPosition = new Vector3(i, 0f, j) - gridCenter + cellCenter; // On soustrait le centre pour avoir le bon offset et on ajoute le centre d'une cellule car on part du coin haut-gauche
                     var obj = Instantiate(cellPrefab, worldPosition, Quaternion.identity, transform);
                }
             }
         }
    Le problème c'est que le compilateur envoie un message d'erreur.
    (All compilers errors have to be fixed before you can enter playmode!).
    Voici la ligne qui envoie le message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var obj = Instantiate(cellPrefab, worldPosition, Quaternion.identity, transform);
    Merci d'avance pour votre aide,

    A+

  8. #8
    Membre émérite
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 654
    Points : 2 335
    Points
    2 335
    Par défaut
    Il va falloir faire un strict minimum d'effort, vraiment minimum là. Un peu de focus :

    cellPrefab => gridCellPrefab

    Le compilateur a dû te le dire que ça n'existait pas, il suffisait juste de voir que c'était juste un nom un peu différent.

    (All compilers errors have to be fixed before you can enter playmode!).
    Et ça ce n'est pas un message d'erreur, c'est un message qui dit qu'il y a des erreurs.

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 170
    Points : 0
    Points
    0
    Par défaut snapping d'un rectangle et d'une grille
    Salut à tous,

    J'aimerais créer une grille de 5x5 afin de déposer un rectangle composé de 5 cubes de taille 1.6f.

    Pour cela j'utilise le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void CreateGrid()
       {
            Vector3 gridCenter = new Vector3(Lignes / 2, 0f, Colonnes / 2); // On calcule le centre de la grille brut
            Vector3 cellCenter = new Vector3(1.6f / 2, 0f, 1.6f / 2); // On calcule le centre d'une cellule
    
            for (int i = 0; i < Colonnes; i++)
            {
                for (int j = 0; j < Lignes; j++)
                {
                    Vector3 worldPosition = new Vector3(i , 0, j) - gridCenter + cellCenter;
                    var obj = Instantiate(gridCellPrefab, worldPosition, Quaternion.identity, transform);
                }
            }
        }
    Le problème c'est que le rectangle ne se snap pas à la grille (on peut voir le rectangle qui dépasse de la grille).
    On voit également que le rectangle est beaucoup plus grand que la taille de la grille.
    Je signale que j'affecte le code à un empty que je centre dans la grille (X = 0, Y = 0, Z = 0).
    J'utilise un gridCellPrefab de taille (X = 0.16f, Y = 0.16f, Z = 0.16f).

    Ici se trouve le code du magnetisme du rectangle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class dragging : MonoBehaviour
    {
        static public GameObject movingObject;
        Vector3 positionZero;
        Plane plane;
     
        private void Start()
        {
     
        }
     
        void Update()
        {
            {
                if (Input.GetMouseButtonDown(0))
                {
                    Ray mouseRay = GetMouseRay();
                    RaycastHit hit;
     
                    if (Physics.Raycast(mouseRay.origin, mouseRay.direction, out hit))
                    {
                        movingObject = hit.transform.gameObject;
                        plane = new Plane(Vector3.up, movingObject.transform.position);
                        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                        float rayDistance;
                        plane.Raycast(ray, out rayDistance);
                        positionZero = movingObject.transform.position - ray.GetPoint(rayDistance);
     
                    }
                }
     
                else if (Input.GetMouseButton(0) && movingObject)
                {
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
     
                    float rayDistance;
     
                    if (plane.Raycast(ray, out rayDistance))
                    {
                        movingObject.transform.position = ray.GetPoint(rayDistance) + positionZero;
                    }
                }
     
                else if (Input.GetMouseButtonUp(0) && movingObject)
                {
                    movingObject = null;
                }
            }
     
            Ray GetMouseRay()
            {
                Vector3 mousePositionFar = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.farClipPlane);
                Vector3 mousePositionNear = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);
                Vector3 mousePositionF = Camera.main.ScreenToWorldPoint(mousePositionFar);
                Vector3 mousePositionN = Camera.main.ScreenToWorldPoint(mousePositionNear);
     
                Ray mouseRay = new Ray(mousePositionN, mousePositionF - mousePositionN);
     
                return mouseRay;
            }
     
            //      if (capsuleToMagnet.magnetMode == true)
            {
                var position = new Vector3(
                Mathf.RoundToInt(movingObject.transform.position.x),
                Mathf.RoundToInt(movingObject.transform.position.y),
                Mathf.RoundToInt(movingObject.transform.position.z));
     
                movingObject.transform.position = position;
            }
        }
    }
    Voici une vidéo qui en dit mieux :
    https://youtube.com/shorts/ISWxzy8_pzM?feature=share

    Merci pour votre aide,

    A+

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/04/2013, 17h43
  2. Réponses: 4
    Dernier message: 05/11/2012, 16h09
  3. Plus court chemin sur une carte vectorielle (pas une grille)
    Par poringkiller dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 05/03/2012, 11h50
  4. Réponses: 2
    Dernier message: 22/07/2011, 12h56
  5. Centrer une image plus large que \textwidth
    Par scalande dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 4
    Dernier message: 01/03/2009, 20h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo