mardi 23 juillet 2019

Unity - Instance dans le monde - partie 2

J'aimerais procéder en mentionnant que j'ai aisément corrigé mon problème d'orientation dans le script d'instanciation. Pour se faire, il m'a simplement fallu supprimer l'information de la collision précédente qui restait enregistrée dans la variable. J'ai intié le script en rendant la rotation locale :
       
             var _maisonRot = _maison.transform.localRotation.eulerAngles;

Et après:

            //changer la rotation du même objet
            var _maisonRot = _maison.transform.rotation;
            _maison.transform.rotation = Quaternion.Euler(-90.0f, Random.Range(-90.0f, 90.0f), 0.0f);
       
J'ai simplement rajouté :

            //repositionner la collision
            _collision = _maison.GetComponent<BoxCollider> ();

qui agit comme un reset.

La suite m'a permis de peaufiner la grosseur des collisions lorsqu'elles varient. J'utilise la propriété .OverlapBox qui, selon ma référence vient générer la collision à l'intérieur du BoxCollider .

OverlapBox agit sur la section encadrée rouge


Dans un premier temps, je crée une variable pour séparer les bâtiments de la surface, ce qui éliminera les analyse superflues dans le cas présent:

  [...]
          
void Start()
            [...]
                  _coucheDeMasqueBatiments = LayerMask.GetMask("Buildings");
            [...]

----

  Dans un second temps, je construis une variable récupérant les coordonnées pour le box collider. Il utilise l'original (Il peut être de n'importe quelle taille, il sera modifié selon la "Bounding Box" ou limites de l'objet visuel.)

            [...]
          
void FixedUpdate()
    {
       
        //création de la boite de collision (nécessite une COLLISION BOX)
        //Démarrer en confirmant les collisions

        var _verifCollision = Physics.OverlapBox ( (_collision.center + _maisonPos), (_collision.size)*1.06f, (_maison.transform.rotation),(_coucheDeMasqueBatiments)); 

 
            [...]


   Ensuite, il est temps d'appliquer ceci dans notre calcul, pour faire en sorte que les maisons ne se touchent pas.

Le résultat nous sort 80% des bâtiments qui évitent de se toucher
Il me reste à investiguer plus en profondeur pour les bâtiments qui s'interpénètrent.
---

Le deuxième élément modifié sur le script me permet de progresser sur l'étape 2 de mon plan : Sur une surface.

Pour l'instant, la surface sera plane; la première étape étant de rendre l'opération modulaire. Si j'étire les X de la surface, les bâtiments pourront se rendre jusqu'à la nouvelle limite. Même situation pour les Z et même situation lorsque la surface est compressée. Mon carré d'origine est de 10 x 10. Voici un résultat avec un rectangle de 5 x 20 :

Les objets en soi ont la même configuration que sur la surface 10 x 10


Pour se faire, j'ai ajouté ces 4 variables au script :

    private BoxCollider _surfaceBox;
    private Vector3 _surfaceMatrix;
    private float _surfaceX;
    private float _surfaceZ;

 
Au démarrage :

         _surfaceBox = _surface.GetComponent<BoxCollider> ();
        _surfaceMatrix = _surfaceBox.bounds.size;
        _surfaceX = _surfaceMatrix.x;
        _surfaceZ = _surfaceMatrix.z;



au début de la mise à jour (rappel) :

        _surfaceX = _surfaceBox.bounds.size.x;
        _surfaceZ = _surfaceBox.bounds.size.z;


et durant la mise à jour, je rajoute ce bout de script :


            //Si la OverlapBox possède un plus grand X que Z; réduit la surface de X (meme chose pour s'il s'agit du Z)
            if (_collision.size.x > _collision.size.z)
            {
                _surfaceX -= (_collision.size.x/2.0f);
                _surfaceZ -= (_collision.size.x/2.0f);
            }
            else
            {
                _surfaceX -= (_collision.size.z/2.0f);
                _surfaceZ -= (_collision.size.z/2.0f);
            }


Ce dernier bout de script empêche l'objet de dépasser de la surface (en prenant en considération que le centre de l'objet se trouve au centre), utilisant soit la largeur soit la longueur dépendamment de quelle mesure est la plus grande. Ainsi, on utilise un seul paramètre pour les deux axes : X et Z.

J'aimerais vous revenir très bientôt avec plus de détail sur l'exercice. D'ici là, je vous dis à bientôt,

David