Comment personnaliser de manière procédurale vos ressources de jeu Unity avec du code

Dans ce tutoriel, je vais vous montrer les bases de l'utilisation de la personnalisation d'objet procédurale à votre avantage, dans Unity. Cela revient essentiellement à utiliser le hasard dans certaines règles. Si vous utilisez une sorte de système procédural (même un simple), vous pouvez ajouter une grande variété de diversité et de détails à votre jeu, sans avoir à tout créer manuellement..

Nous commencerons par créer manuellement une arborescence simple, puis nous utiliserons des techniques de personnalisation procédurale pour automatiser la création d'une gamme d'arbres similaires, mais notablement différents. Ensuite, nous placerons ces arbres dans un jeu simple, pour montrer à quoi ils ressemblent en "action".

Voici à quoi ressembleront nos arbres générés de manière procédurale:


Cliquez sur le bouton pour générer un nouvel ensemble d'arbres..

Installer

Comme dans mon précédent tutoriel, vous devez installer Unity et en avoir une connaissance de base. (Voir Comment apprendre l'unité pour un bon endroit pour commencer.)

Créez un nouveau projet pour ce tutoriel et cochez la case intitulée contrôleurs de caractères; nous pourrions en avoir besoin plus tard.

J'ai préparé des arbres que nous utiliserons, que vous pouvez trouver dans le Fichiers 3d dossier du téléchargement source. Les fichiers de projet complets, au cas où vous souhaiteriez les utiliser, peuvent également être trouvés dans le téléchargement source, mais ne sont pas nécessaires pour ce tutoriel..

Prêt? Allons-y!


Créer un arbre

Commençons par créer un simple arbre car, pour pouvoir ajouter des touches de procédure, nous avons besoin d’un modèle de base..

Placez les fichiers 3D que j'ai mentionnés ci-dessus dans le dossier des ressources. N'oubliez pas de définir la mise à l'échelle de l'importateur sur 1 plutôt que 0,001, de sorte que les tailles s'alignent.

Maintenant, créez un cube et nommez-le Arbre. Aller au Filtre à mailles composant et échanger le maillage de cube pour la tree_01 engrener. Il devrait apparaître si vous avez les fichiers 3D dans votre dossier.

L'arbre peut ne pas apparaître complètement. En effet, le modèle 3D de l'arbre prend en charge deux matériaux (écorce et feuilles), mais il est toujours défini sur un matériau. Pour résoudre ce problème, ouvrez le Matériaux tableau dans le Rendu de maille composant du cube et définissez le Taille à 2. Ça devrait ressembler à ça:

Nous avons maintenant besoin de matériaux pour l'écorce et les feuilles. Créez deux nouveaux matériaux et donnez-leur une couleur de base marron et verte. Attribuer ces deux matériaux à la matériaux fente dans le Rendu de maille de l’arbre, et il devrait apparaître avec les matériaux affichés, comme ceci:

Pour terminer cet arbre de base, ajoutez un collisionneur de capsules en cliquant sur Composant> Physics> Capsule Collider. C'est pour que nous ne passions pas "à travers" l'arbre lorsque nous le testerons plus tard. Unity vous demandera si vous souhaitez remplacer le collisionneur de boîtes actuel sur l’arbre, ce que vous devrez confirmer. Une fois le nouveau collisionneur ajouté, modifiez les valeurs afin que la forme de la capsule chevauche grossièrement le tronc de l'arbre, comme suit:

Ces valeurs fonctionneront:

Maintenant, placez l’arbre dans le dossier du projet pour le transformer en préfabriqué. Notre arbre de base est terminé!


Rotation aléatoire des arbres

Créez un nouveau script appelé tree.js et l'ajouter à l'arbre préfabriqué. Maintenant, ajoutez les lignes suivantes à la Début() une fonction:

transform.localEulerAngles.y = Random.Range (0, 360);

L’arborescence subira maintenant une rotation aléatoire sur l’axe des Y lors de sa création. Cela signifie que si vous placez une rangée d’arbres, procédez comme suit:

… Puis ils se tournent tous dans leur propre direction au début du jeu. Mettez un tas d'arbres dans votre niveau et essayez-le!


Ajuster la taille

De la même manière, nous pouvons modifier la taille de tout objet. Ajoutez le code suivant au tree.js scénario:

transform.localScale = transform.localScale * Random.Range (0.5, 1.5);

Cela réduira ou augmentera la taille de l'arbre. Si vous commencez avec une échelle de 1 (ce qui devrait être le cas si tout est configuré correctement), la nouvelle échelle sera comprise entre 0,5 (moitié plus grande) et 1,5 (50% plus grande). Maintenant, vos arbres devraient paraître encore plus diversifiés:


Utiliser différents modèles 3D

Vous avez peut-être remarqué qu'il y a en fait trois arbres dans les fichiers que je vous ai donnés plus tôt. En effet, nous allons maintenant remplacer le modèle 3D par un autre modèle de manière aléatoire, en créant encore plus d'arbres à partir du modèle..

Pour ce faire, ajoutez le code suivant à la commande tree.js scénario:

var treeMeshes: Mesh []; function Start () gameObject.GetComponent (MeshFilter) .mesh = treeMeshes [Random.Range (0, treeMeshes.Length)]; 

Cependant, avant de commencer la scène, assignez les trois mailles que nous avons à ce tableau, comme ceci:

Si vous jouez votre scène, vous remarquerez que vous obtenez maintenant trois maillages différents, attribués de manière aléatoire..

Vous pouvez tester tout cela dans la démo ci-dessous. Si vous appuyez sur le bouton, tous les arbres seront remplacés par de nouveaux et uniques..


Changer la couleur

Celui-ci pourrait être un peu délicat. En plus de toutes les fonctionnalités précédentes, nous donnerons à chaque arbre une nuance unique de vert et de brun.

Premièrement, nous devons savoir comment accéder aux couleurs. Le matériau d’un objet est généralement accessible via renderer.material.color. Dans notre cas, cependant, nous avons deux couleurs, ce qui signifie que nous devons y accéder via renderer.materials [0] .color et renderer.materials [1] .color. Vérifiez le rendu du maillage de l'arbre pour voir quel matériau (feuilles ou écorce) se trouve dans l'emplacement 0 et lequel se trouve dans l'emplacement 1.

La création d'une couleur aléatoire fonctionne de manière similaire aux étapes précédentes. Si vous ajoutez ces lignes:

renderer.materials [0] .color = Couleur (Plage aléatoire (0, 1,1), Plage aléatoire (0, 1,1), Plage aléatoire (0, 1,1)); renderer.materials [1] .color = Couleur (Plage aléatoire (0, 1,1), Plage aléatoire (0, 1,1), Plage aléatoire (0, 1,1));

… Alors le matériau de l'écorce et celui de la feuille se verront attribuer une toute nouvelle couleur. Regardons ça:

D'accord, ce n'est pas ce que nous visons réellement. Ce sont des couleurs aléatoires de tout le spectre disponible! Pour les objets artificiels, comme les voitures, cela pourrait suffire. Mais nous avons des arbres, nous avons donc besoin de verts et de bruns.

Remplacez le code de couleur que nous venons d'ajouter par ceci:

renderer.materials [0] .color = Couleur (Plage aléatoire (0,8, 1,1), Plage aléatoire (0,4, 0,6), Plage aléatoire (0, 0,2)); renderer.materials [1] .color = Couleur (Plage aléatoire (0, 0,4), Plage aléatoire (0,6, 1,1), Plage aléatoire (0, 0,4));

Et essayez-le:

Beaucoup mieux. (Si soudainement les feuilles sont brunes et le tronc vert, échangez les 1 et 0 dans renderer.materials [0].)

Le code produit une nouvelle couleur au début de la couleur du programme. Les trois valeurs aléatoires vont de 0 (minimum) à 1 (maximum), qui correspondent alors aux valeurs rouge, verte et bleue de la couleur. En limitant la portée du hasard, comme en disant Plage aléatoire (0,3, 0,6), les valeurs sont limitées à une certaine plage. Cela nous permet de créer une gamme de nouvelles couleurs toujours "vertes" ou la couleur que nous pourrions spécifier..


Incliner l’arbre (facultatif)

Ceci est juste un petit tweak, mais un joli quand même. Nous pouvons donner à l’arbre une légère inclinaison d’un côté, ce qui élimine ce sentiment "proprement placé" qui aurait pu se produire auparavant.

transform.localEulerAngles.x = Random.Range (-10, 10);

Cette fois, une très petite rotation est appliquée sur l’axe des x, ce qui permet à l’arbre de s’incliner dans cette direction. Pour vous assurer qu'il n'y a pas de "trou" entre les racines et le sol de l'arbre, le "pivot" (ou le centre) des treillis est légèrement au-dessus des racines, ce qui signifie qu'il y a suffisamment de marge de manœuvre..

Le script d'arborescence entier devrait ressembler à ceci:

var treeMeshes: Mesh []; function Start () transform.localEulerAngles.y = Random.Range (0, 360); transform.localEulerAngles.x = Random.Range (-10, 10); transform.localScale = transform.localScale * Random.Range (0.5, 1.5); gameObject.GetComponent (MeshFilter) .mesh = treeMeshes [Random.Range (0, treeMeshes.Length)]; renderer.materials [0] .color = Couleur (Plage aléatoire (0,8, 1,1), Plage aléatoire (0,4, 0,6), Plage aléatoire (0, 0,2)); renderer.materials [1] .color = Couleur (Plage aléatoire (0, 0,4), Plage aléatoire (0,6, 1,1), Plage aléatoire (0, 0,4)); 

Vous pouvez tout essayer dans cette démo:


Créer un niveau de procédure simple

Voyons comment ils se sentent dans un jeu réel.

Mettez un avion au sol et agrandissez-le. Ce sera notre "sol" pour le niveau. Pendant que vous y êtes, créez un matériau de sol et affectez-le au sol. Définissez le facteur d'échelle de l'avion sur 50.1.50, donc nous avons assez de place.

Ensuite, mettez un contrôleur à la première personne dans la scène. Vous le trouverez dans les contrôleurs de personnage importés au début du didacticiel. (Si vous ne les avez pas, cliquez sur Biens> Package d'importation> Contrôleurs de caractères). Après avoir placé les contrôleurs FPS, retirez la caméra principale. le contrôleur est livré avec le sien, nous n’avons donc plus besoin de la caméra. Ajoutez également une lumière directionnelle.

Pour créer automatiquement des arbres, créez un nouveau fichier JavaScript et nommez-le. treeGenerator.js. Mettez le code suivant dedans:

var treePrefab: GameObject; var numberOfTrees: int = 20; fonction Start () pour (var i: int = 0; i < numberOfTrees; i++) Instantiate(treePrefab, Vector3(transform.position.x + Random.Range(-40.0, 40.0), 0, transform.position.z + Random.Range(-40.0, 40.0)), transform.rotation); 

Mettre le treeGenerator.js script sur le plancher, attribuez le préfabriqué à la treePrefab emplacement variable, et essayez-le:

Et fait! Maintenant, vous avez un jeu exploratoire simple, qui créera un niveau unique à chaque exécution.

Améliorations ultérieures

Le jeu que vous avez peut maintenant être énormément étendu. Vous pouvez ajouter plus de plantes, comme des palmiers ou des arbustes. Vous pouvez ajouter d'autres objets, comme des roches ou des pommes. Ou vous pouvez ajouter une sorte de pièce de monnaie ou de micros, que le joueur pourrait écraser pour augmenter son score.


Conclusion

Les touches procédurales sont un moyen simple et efficace de créer des détails automatiquement. Au lieu d'avoir dix objets, vous pourriez avoir infiniment nombreux.

Vous pouvez utiliser les éléments avec lesquels nous avons joué dans votre propre jeu, ou vous pouvez les démonter et les réécrire pour répondre à vos besoins. Par exemple, j'ai créé un système qui crée différentes longueurs de bambou:

Vous pouvez faire des voitures avec des éléments variables ou placer automatiquement des ennemis dans un niveau. Les possibilités sont infinies.