Bonnes pratiques pour grand terrain sur scène

Questions techniques liées à l’utilisation d'Unity (et n'entrant pas dans le cadre d'une des sections suivantes)
Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

Bonnes pratiques pour grand terrain sur scène

Message par Meudes » 05 Juil 2021 16:10

Bonjour la communauté unity3d-france.com ! :happy1:

Grand débutant sur Unity mais papi développeur, j'aimerais avoir un avis éclairé sur une architecture.

Nous avons dans la scène un terrain de 1000 x 1000.
Celui-ci est entouré de 8 autres de même taille.
A chaque passage d'un terrain à un autre, on charge les terrains manquant et on destroye les terrains en surplus :

Les personnages (MLAPI) ont une Camera à 1000/ 800 unités de vision.

L'un va à droite et traverse la "frontière" :
Il récupère les caractéristiques des terrains à charger par le serveur pour son client.

légende :
--------
x personnage
[] terrain
" à instancier (charger)
! à destroyer (détruire)


Code : Tout sélectionner

Origine :     Passage de "frontières" :
[][ ][]        [!][][ ]["]
[][x][] =>     [!][][x]["]
[][ ][]        [!][][ ]["]
Est-ce comme cela que l'on fait pour avoir une grande scène ? :mrgreen:
Est-ce une une bonne stratégie, une bonne pratique (ou je me coupe les cheveux en 4 et faire une scène gigantesque marche tout seul par "magie" avec Unity ?), la plateforme finale étant Windows, Linux, MacOs ?

---

Prefab ? Venant d'un monde où tout est sql, les préfabs ont du mal à rentrer dans ma cervelle. :pasdrole:

Afin d'instancier des "Trucs" sur mon terrain ma stratégie est la suivante :
Je créer une class c_Objet avec des variables par exemple pointDeVieMax et pointDeVieActuel,
modifiable par l'inspecteur (ou scripts) et quelques méthodes partagées à tous mes objets.

Tous mes préfabs "Objets" ont le script c_Objet (j'ai un c_Objet qui héritent du préfab ??).

Lors de la lecture des infos du serveur (retournant les noms des prefabs "à spwaner", leurs positions, les caracs modifiables (pointDeVieActuel par exemple),
J'instance mes objets par préfabs sur les terrains a charger et je les met dans un dico (ou autre conteneur).

Est-ce une bonne pratique ? :mrgreen:

Merci par avance.
Mes mots ne sont pas forcément précis, ne pas hésiter à me corriger :merci:
Au plaisir d'échanger avec vous ! :taré1:

Avatar de l’utilisateur
DevAmat
Messages : 435
Inscription : 23 Nov 2016 11:50

Re: Bonnes pratiques pour grand terrain sur scène

Message par DevAmat » 05 Juil 2021 23:25

Salut.
Pour commencer, je précise que je ne suis pas un expert en création de monde ouvert.
L'idée de diviser le monde en cellule est la bonne. Charger et décharger en continu est une bonne pratique.

Je dirais que dans un premier temps, il faut définir la taille de ton monde.

- Si il n'est pas trop grand, il n'y aura pas à remettre le joueur à l'origine de monde, "origin shifter" en anglais. Ce qui veut dire que déjà tu peux mettre en "static" la plupart des "mesh" dans tes cellules.
Ensuite, je te conseille de créer ton monde, puis de le dispatcher dans différentes scènes qui seront chargées et déchargées pendant le jeu (le chargement et le déchargement de scène est plus facile pour Unity).

- Dans le cas d'un monde très grand qui nécessite le "origin shifter", alors tout doit être dynamique car tu as le besoin de modifier la position de tous les "GameObject" de la scène. Dans ce cas, tes cellules sont contenues ton des "prefab" et non plus dans des scène.

La première méthode est beaucoup plus optimisé mais convient à un monde pas trop grand..

Il faut aussi décider de la taille de tes cellules, et là cela dépend de ce qu'il y a dedans. Il faut surveiller la mémoire et ne pas hésiter à réduire la taille des cellules (cela en fera plus mais les chargements et déchargements seront moins lourds).

Je rajoute aussi la notion de "Addressables" :
https://docs.unity3d.com/Manual/com.uni ... ables.html
Unity blog sur le sujet:
https://blog.unity.com/technology/tales ... dressables
Cela aide à gérer la mémoire. Cela peut être très important surtout dans un open world, mais cela nécessite une grosse organisation et l'utilisation "asset bundle" pour charger des éléments.

Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

Re: Bonnes pratiques pour grand terrain sur scène

Message par Meudes » 06 Juil 2021 11:23

Merci pour cette réponse !

Point d'outil magique donc ... :pleur4:

Bon en difficulté : c'est terrible, c'est beaucoup plus affreux que je l'envisageais 8/
J'ai encore des zones d'ombres sur l'Origin Shifter.
Mais pour résumer : si on est trop loin sur un axe, ça merdouille, il faut se recentrer.

Top pour la doc des addressables !


Donc si je synthétise la méthode (pour d'éventuels développeurs séduit par l'open world) :

Outil génération de map :
- Outil de génération de la map (Perlin Noise) et "résolution" (vertex max / unité)
- Modif de l'outil : génération en "tuiles"
- Modif de l'outil : ajout d'objets spawns

Outil de sauvegarde -> transformer tout cela en string, int, float et arrays qui peux être sauvegardé en fichier et transféré en réseau, monté en RAM
- Modif : ajouter méthodes lectures
- Modif : ajouter une méthode de translation de l'origin qui ne flingue pas le CPU :mrgreen:

Outil de fabrication d'une tuile :
- Réception des caracs d'une tuile : et {création} / peut-être ... on les générer avant et les charger ailleurs...
- Outil de chargement en RAM des objets/autres spawns

->Et enfin : Outil de chargement / déchargement, de tuile suivant la position du Player.

J'aurai fini dans 12 ans. :hehe:
C'est top, Merci encore pour ton aide, c'est qu'avant de partir dans un machin aussi affreux,
il me fallait confronter cette idée. :hello:

Avatar de l’utilisateur
jmhoubre
Messages : 856
Inscription : 05 Oct 2019 22:05

Re: Bonnes pratiques pour grand terrain sur scène

Message par jmhoubre » 06 Juil 2021 16:45

Quelques mots sur l'origin shifter. Ce terme désigne une solution pour régler le problème du à l'imprécision des différentes représentations informatique des nombres réels. Un flottant (ou un double) n'est pas un nombre réel. La quasi totalité des réels ne sont pas représentables exactement par un flottant, et subissent donc un arrondi lors de leur conversion. La nécessité d’arrondir rend les opérations, même les plus simples comme l’addition, non triviales. La manière précise de les effectuer est définie dans la norme IEEE 754. L'addition, opération basique s'il en est, de deux réels contient d'emblée trois approximations dues aux 3 opérations d'arrondis. Exemple : 0.1 + 0.2 - 0.3 n'est pas égale à zéro :

Code : Tout sélectionner

private void Start ()
{
    float x = 0.1f;
    float y = 0.2f;
    float z = 0.3f;
    Debug.Log ($"0.1f+ 0.2f - 0.3f = : {x + y - z}");
}
mais donne -7,450581E-09. En conséquence, il est délicat de comparer des résultats d'opérations sur des flottants, comme par exemple déterminer si un objet a atteint sa destination : on compare 2 Vector3, composés de 3 flottants.
Un nombre réel n’est donc qu’imparfaitement rendu par un float ou même un double. Des erreurs peuvent s’accumuler lors des calculs. Pour comparer deux float, il est recommandé d’utiliser ceci :
  • public static float Epsilon : la plus petite valeur non nulle.
  • public static bool Approximately (float a, float b) : compare a et b, et renvoie true si la différence vaut moins qu’Epsilon.
Autre difficulté (parmi d'autres), un phénomène appelé absorption : si un nombre très grand (comme un milliard) est additionné avec un nombre très petit (comme un milliardième), le résultat montre que le petit nombre a été absorbé par le grand, comme si l'opération n'avait pas eu lieu. Ainsi cette opération affiche True.

Code : Tout sélectionner

private void Start ()
{
    float x = 1000000000f;
    float y = 1 / x;

    Debug.Log (x + y == x);
}
De plus, une même opération sur deux plateformes différentes (un PC, un mac, une PS4, ...) peut donner des résultats différents, car la norme laisse une marge pour l'implémenter.

Enfin, certaines propriétés du corps des réels (l'ensemble mathématique des réels) ne sont plus vraies avec les flottants : si la commutativité est conservée (a + b = b + a), ce n'est pas le cas de l'associativité : (a + b) + c # a + (b + c), ni la distributivité : a x (b + c) # (a x b) + (a x c) (arrive quand b + c est très grand et a petit.

Lire l'article de Wikipédia sur les nombres flottants pour plus de détails.

Utiliser des doubles ou des décimaux est une idée, mais d'une part la librairie Mathf est définie pour des flottants, il faut utiliser la classe Math de .Net dans l'espace de noms System, et d'autre part le problème est déplacé pas pas résolu.

Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

Re: Bonnes pratiques pour grand terrain sur scène

Message par Meudes » 07 Juil 2021 10:05

mmmmmmmm, tout s'explique !!
, il est recommandé d’utiliser ceci :

public static float Epsilon : la plus petite valeur non nulle.
public static bool Approximately (float a, float b) : compare a et b, et renvoie true si la différence vaut moins qu’Epsilon.
Pour la gestion de la caméra, nous avions un problème d'arrondi sur une comparaison de vector3.
On s'est arraché les cheveux dessus à deux pendant 3 heures avant d'abandonner et faire une bidouille mathématique peu propre...

Merci Jmhoubre c'est beaucoup plus clair ! :super:
0.1 + 0.2 -0.3 # 0 je le répète a mon banquier depuis des années ... ::d

J'ai trouvé ce tuto (fr) concernant l'OpenWorld :

https://youtu.be/cNY2s5Kq9lE
A première vue, que du bonheur !

Avatar de l’utilisateur
jmhoubre
Messages : 856
Inscription : 05 Oct 2019 22:05

Re: Bonnes pratiques pour grand terrain sur scène

Message par jmhoubre » 07 Juil 2021 10:45

C'est une reprise d'une série de Sebastan Lague, mais il manque 2 ou 3 épisodes (corrections et reprise de code). Elle est très intéressante, et montre comment améliorer une génération de terrain (basée sur du bruit de Perlin ) en utilisant des chunks et des threads.

Répondre

Revenir vers « Unity le logiciel »