Gestion d'actifs procéduraux dans Unity

Nous avons déjà envisagé d’ajouter nos propres outils à l’éditeur de Unity; Maintenant, dans ce court tutoriel, je vais vous présenter le traitement des actifs par script dans Unity. Nous allons gérer les chemins, créer des fichiers préfabriqués, générer une texture et l'enregistrer dans une image. Enfin, nous allons également créer un fichier de matière qui utilise l’image générée, et tout cela sera fait par code..


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler:


Étape 1: Configurer le projet

Créer un projet vide; nous n'utiliserons rien d'extraordinaire ici, nous ne devrions donc pas prendre la peine d'importer quoi que ce soit. Une fois cela fait, créez un script d’éditeur. Unity ne nous laissera utiliser ses classes d’éditeur que si nous plaçons notre script dans un dossier nommé Éditeur. Comme cela n’existe pas encore dans notre projet, nous devons le créer..

Créons maintenant un script à l'intérieur.


Étape 2: Ajouter un élément de menu

Nettoyons notre script. Outre les fonctionnalités de base, nous souhaitons également pouvoir utiliser les classes de l'éditeur. Nous devons être en utilisant UnityEditor et la classe de notre script devrait étendre la Éditeur classe au lieu de MonoBehaviour comme le font les objets de jeu normaux.

 utiliser UnityEngine; using System.Collections; utiliser UnityEditor; Classe publique Exemples: Editor 

Dans notre première fonction, nous allons travailler avec des préfabriqués, appelons-le un PrefabRoutine.

 Classe publique Exemples: Editor void PrefabRoutine () 

Pour exécuter facilement cette fonction depuis l’éditeur, ajoutons-le en tant que Élément du menu.

 Classe publique Examples: Editor [MenuItem ("Examples / Prefab Routine")] void PrefabRoutine () 

En plus de faire savoir à l’unité que nous voulons que cette fonction soit exécutable à partir du Exemples-> Routine préfabriquée ", nous devons également rendre cette fonction statique.

 Classe publique Examples: Editor [MenuItem ("Examples / Prefab Routine")] static Void PrefabRoutine () 

Si vous revenez à l'éditeur maintenant (et actualisez le menu), vous remarquerez qu'il y a un nouveau menu nommé Exemples Là.

Si vous sélectionnez le Routine Préfabriquée rien ne se passera puisque notre fonction est vide.


Étape 3: créer un dossier

Pour façonner notre projet comme nous le voulons, nous devons savoir comment créer des dossiers afin de pouvoir déplacer des éléments. La création d'un dossier à partir du script est très simple. Tout ce que nous avons à faire, c'est d'indiquer à l'unité où le dossier doit être placé. Pour créer un dossier, nous devons utiliser AssetDatabase classe.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Dossier préfabriqué"); 

"Les atouts" est le nom du dossier parent du répertoire que nous voulons créer. Dans notre cas, c’est le dossier principal du projet où tous nos actifs sont importés / créés..

Notez que vous pouvez également utiliser le .NET Annuaire classe. Cela vous permettra également de supprimer, déplacer ou accéder aux fichiers des répertoires. Pour utiliser cette classe, vous devez être en utilisant System.IO.

Chaque fois que vous sélectionnez le Routine Préfabriquée depuis l'éditeur, un nouveau dossier doit être créé et visible dans la vue du projet.


Étape 4: Créer un préfabriqué

Pour créer un préfabriqué, nous devons appeler EditorUtility.CreateEmptyPrefab (). La fonction prend le chemin du préfab en argument.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Dossier préfabriqué"); Object prefab = EditorUtility.CreateEmptyPrefab ("Actifs / Dossier préfabriqué / obj.prefab"); 

N'oubliez pas l'extension! De plus, après avoir créé le fichier, nous devons appeler AssetDatabase.Refresh (), donc l'unité est capable de le voir.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Dossier préfabriqué"); Object prefab = EditorUtility.CreateEmptyPrefab ("Actifs / Dossier préfabriqué / obj.prefab"); AssetDatabase.Refresh (); 

Si nous laissons un chemin constant comme argument, chaque fois que nous sélectionnons notre routine, un nouveau préfabriqué vide remplacera l'ancien. Attribuons chaque préfabriqué à un dossier séparé pour contrer cela. Pour ce faire, nous devons enregistrer le dernier dossier créé dans une chaîne afin de pouvoir l'utiliser ultérieurement comme argument de chemin. le Créer le dossier la fonction retourne un GUID, qui est fondamentalement l'ID du fichier (ou du répertoire). Il existe une fonction qui récupère le chemin si nous soumettons cet ID. C'est appelé GUIDToAssetPath; Utilisons-le pour obtenir le chemin de notre dossier.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Actifs", "Dossier préfabriqué")); Object prefab = EditorUtility.CreateEmptyPrefab ("Actifs / Dossier préfabriqué / obj.prefab"); AssetDatabase.Refresh (); 

Maintenant, utilisons le chemin pour diriger les prefabs que nous allons créer dans le dossier créé le plus récemment.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Actifs", "Dossier préfabriqué")); Object prefab = EditorUtility.CreateEmptyPrefab (chemin + "/obj.prefab"); AssetDatabase.Refresh (); 

Vous pouvez tester si les préfabriques vides créés sont maintenant compressés dans des dossiers..


Étape 5: Définir le préfabriqué

Si vous créez un préfabriqué, vous ne voudrez probablement pas le laisser vide car dans ce cas, il est pratiquement inutile. Définissons notre préfabriqué s'il y a un objet de jeu sélectionné pendant l'exécution de notre routine. Nous allons le préfabriqué à l'objet sélectionné. Pour obtenir l'objet actuellement sélectionné, nous pouvons utiliser le Sélection classe qui a une référence à elle. Pour définir le préfabriqué, nous devons appeler ReplacePrefab ().

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Actifs", "Dossier préfabriqué")); Object prefab = EditorUtility.CreateEmptyPrefab (chemin + "/obj.prefab"); AssetDatabase.Refresh (); if (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab); 

Si vous exécutez la routine avec n'importe quel objet du jeu sélectionné, vous remarquerez que le préfabriqué créé est automatiquement défini..

Ça y est, nous avons créé une routine personnalisée pour la création de préfabriqués, ce n'est pas très utile mais vous devriez être capable de le faire maintenant si cela sera nécessaire dans votre projet..

À la fin, je tiens également à mentionner que AssetDatabase vous permet également de déplacer des éléments, de les déplacer vers la corbeille ou de les supprimer en appelant AssetDatabase.MoveAsset (), AssetDatabase.MoveAssetToTrash () et AssetDatabase.DeleteAsset () respectivement. Le reste de la fonctionnalité peut être trouvé à AssetDatabase page de référence du script.


Étape 6: Ajouter un autre élément de menu

Passons à un autre exemple. Cette fois, nous allons créer une texture et un matériau par programmation. Appelons cet élément de menu Routine Matériel.

 [MenuItem ("Examples / Prefab Routine")] statique void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Actifs", "Dossier préfabriqué")); Object prefab = EditorUtility.CreateEmptyPrefab (chemin + "/obj.prefab"); AssetDatabase.Refresh (); if (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab);  [MenuItem ("Examples / Material Routine")] statique void MaterialRoutine () 

Maintenant, nous avons deux articles à choisir dans le Exemples menu.


Étape 7: Créer une texture

Créons un Texture2D et définir sa taille à (256, 256) pour cet exemple.

 [MenuItem ("Examples / Material Routine")] statique void MaterialRoutine () Texture2D tex = new Texture2D (256, 256); 

Maintenant, nous ne devrions pas laisser tous ces pixels disparaître, alors définissons les pixels de la texture selon une sorte de formule élaborée. Pour cela nous aurons besoin de deux pour des boucles pour parcourir chaque pixel. Pour définir la couleur de chaque pixel, nous devons appeler SetPixel () qui prend la position du pixel sur une texture et sa couleur comme arguments.

 [MenuItem ("Examples / Material Routine")] statique void MaterialRoutine () Texture2D tex = new Texture2D (256, 256); pour (int y = 0; y < 256; ++y)  for (int x = 0; x < 256; ++x) tex.SetPixel(x, y, new Color());  

Pour attribuer la couleur, nous allons utiliser le Mathf.Sin () une fonction. le Couleur La classe peut être initialisée avec trois flottants, correspondant respectivement aux composantes de couleur rouge, verte et bleue. La valeur maximale autorisée est 1 et min est 0, alors le Péché() la fonction convient parfaitement à nos besoins.

 pour (int y = 0; y < 256; ++y)  for (int x = 0; x < 256; ++x) tex.SetPixel(Mathf.Sin(x*y), Mathf.Sin(x*y), Mathf.Sin(x*y))); 

Peu importe ce que nous soumettons à la Péché() fonction, mais pour obtenir quelque chose de plus intéressant, nous devrions donner une valeur qui change pour chaque pixel.


Étape 8: Créer une image

Créons maintenant une image à partir de la texture que nous venons de créer. Puisque nous allons écrire dans un fichier en mode binaire, nous devons être en utilisant System.IO, alors ajoutons-le en haut de notre script.

 utiliser UnityEngine; using System.Collections; utiliser UnityEditor; using System.IO; Classe publique Exemples: Editor

Pour enregistrer notre texture en tant que PNG image nous devons d'abord appeler EncodeToPNG () qui retournera un tableau d'octets que le PNG le fichier est constitué de.

 pour (int y = 0; y < 256; ++y)  for (int x = 0; x < 256; ++x) tex.SetPixel(x, y, new Color(Mathf.Sin(x*y), Mathf.Sin(x*y), Mathf.Sin(x*y)));  byte[] pngData = tex.EncodeToPNG();

Maintenant que nous avons notre pngData nous pouvons l'écrire dans un fichier et créer un PNG l'image de cette façon.

 octet [] pngData = tex.EncodeToPNG (); if (pngData! = null) Fichier.WriteAllBytes ("Assets / texture.png", pngData);

Puisque nous créons le fichier avec un chemin constant, nous allons chaque fois exécuter MaterialRoutine (), la texture sera écrasée.

Et puisque nous avons notre image, nous n’avons plus besoin de la texture générée, car elle ne fera de toute façon pas référence à une image. Détruisons le.

 octet [] pngData = tex.EncodeToPNG (); if (pngData! = null) Fichier.WriteAllBytes ("Assets / texture.png", pngData); DestroyImmediate (tex);

De plus, nous devons laisser Unity mettre à jour la vue du projet et les références de fichiers. pour ce faire, nous devons appeler AssetDatabase.Refresh ().

 octet [] pngData = tex.EncodeToPNG (); if (pngData! = null) Fichier.WriteAllBytes ("Assets / texture.png", pngData); DestroyImmediate (tex); AssetDatabase.Refresh ();

Testons si la texture est créée lors de l'exécution de notre routine.


Étape 9: Créer un matériau

Nous avons une image et nous pouvons maintenant créer un matériau qui l'utilise comme texture. Créons un nouveau matériel.

 AssetDatabase.Refresh (); nouveau matériau (Shader.Find ("Diffuse"));

Le matériel créé utilisera un Diffuser shader. Pour enregistrer ce matériel dans le fichier, nous pouvons appeler AssetDatabase.CreateAsset (). Cette fonction prend un actif comme premier argument et le chemin comme second..

 AssetDatabase.Refresh (); AssetDatabase.CreateAsset (new Material (Shader.Find ("Diffuse")), "Assets / New Material.mat");

Si vous exécutez notre routine maintenant, vous verrez que le matériau est créé.

Comme vous pouvez le voir, tout est correct, son nom est Nouveau matériel et il utilise Diffuser shader, mais aucune texture ne lui est attribuée.


Étape 10: Attribuer la texture

Nous devons d’abord faire référence au matériel que nous venons de créer. Nous pouvons l'obtenir en appelant AssetDatabase.LoadAssetAtPath () qui charge l'actif et renvoie sa référence.

 AssetDatabase.CreateAsset (new Material (Shader.Find ("Diffuse")), "Assets / New Material.mat"); Material Material = (Material) (AssetDatabase.LoadAssetAtPath ("Assets / New Material.mat", typeof (Material)));

Attribuons maintenant notre texture générée en tant que texture principale du matériau. Nous pouvons obtenir la référence de texture de la texture générée de la même manière que nous avons obtenu la référence de matériau.

 Material Material = (Material) (AssetDatabase.LoadAssetAtPath ("Assets / New Material.mat", typeof (Material))); material.mainTexture = (Texture2D) (AssetDatabase.LoadAssetAtPath ("Assets / texture.png", typeof (Texture2D)));

Pour voir les résultats, lancez le Routine Matériel.

Comme vous pouvez le constater, le matériau a la texture assignée maintenant.

Conclusion

C'est la fin de l'introduction pour gérer vos actifs à l'aide de scripts. Si vous souhaitez approfondir vos connaissances sur le sujet, vous pouvez visiter la page de référence des classes de l'éditeur Unity, en particulier la référence au script AssetDatabase mérite d'être examinée. Si vous devez travailler à un niveau bas, vous devez également lire la documentation sur System.IO pour obtenir plus d'informations sur ses classes et sur la manière de les utiliser. Merci pour votre temps!