We hebben eerder gekeken naar het toevoegen van onze eigen tools aan de editor van Unity; nu, in deze korte tutorial, zal ik je voorstellen om de assets in scriptie te verwerken in Unity. We zullen paden beheren, prefab-bestanden maken, een textuur genereren en deze in een afbeelding opslaan. Ten slotte zullen we ook een materiaalbestand maken dat de gegenereerde afbeelding gebruikt, en dit alles zal door code worden gedaan.
Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:
Maak een leeg project; we zullen hier niets speciaals gebruiken, dus we zouden helemaal geen moeite moeten doen om iets te importeren. Zodra dat is gebeurd, maakt u een editor-script. Unity zal ons zijn editorlessen alleen laten gebruiken als we ons script in een map plaatsen met de naam Editor. Omdat dat nog niet bestaat in ons project, moeten we het maken.
Laten we nu een script erin maken.
Laten we ons script opruimen. Naast de basisfunctionaliteit willen we ook de editorlessen kunnen gebruiken. We moeten zijn met UnityEditor
en de klasse van ons script zou het moeten uitbreiden Editor
klasse in plaats van MonoBehaviour
zoals normale game-objecten doen.
gebruikmakend van UnityEngine; met behulp van System.Collections; gebruikmakend van UnityEditor; openbare klassenvoorbeelden: Editor
In onze eerste functie zullen we werken met prefabs, laten we het a noemen PrefabRoutine
.
public class Examples: Editor void PrefabRoutine ()
Om deze functie gemakkelijk uit te voeren vanuit de editor, laten we het toevoegen als een Menu onderdeel
.
public class Voorbeelden: Editor [MenuItem ("Examples / Prefab Routine")] void PrefabRoutine ()
Afgezien van het laten weten van de eenheid dat we willen dat deze functie uitvoerbaar is vanuit de Voorbeelden-> Prefab-routine ", we moeten deze functie ook statisch maken.
public class Voorbeelden: Editor [MenuItem ("Examples / Prefab Routine")] static void PrefabRoutine ()
Als je nu teruggaat naar de editor (en het menu vernieuwt), zul je merken dat er een nieuw menu met de naam is Voorbeelden er.
Als u de Prefab Routine er gebeurt niets omdat onze functie leeg is.
Om ons project vorm te geven zoals we willen, moeten we weten hoe we mappen kunnen maken, zodat we dingen kunnen verplaatsen. Het maken van een map vanuit het script is heel eenvoudig, het enige wat we moeten doen is de eenheid laten weten waar de map moet worden geplaatst. Om een map te maken die we moeten gebruiken AssetDatabase
klasse.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Prefab Folder");
"Middelen" is de naam van de bovenliggende map van de map die we willen aanmaken. In ons geval is dit de hoofdprojectmap waarin al onze assets worden geïmporteerd / gemaakt.
Merk op dat u ook .NET kunt gebruiken directory
klasse. Hiermee kunt u ook de mappenbestanden verwijderen, verplaatsen of openen. Om deze klasse te gebruiken, moet je zijn met behulp van System.IO
.
Elke keer dat u de Prefab Routine van de editor moet een nieuwe map worden gemaakt en zichtbaar zijn in de projectweergave.
Om een prefab te maken, moeten we bellen EditorUtility.CreateEmptyPrefab ()
. De functie neemt het prefab-pad als een argument.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Prefab Folder"); Object prefab = EditorUtility.CreateEmptyPrefab ("Assets / Prefab Folder / obj.prefab");
Vergeet de extensie niet! Nadat we het bestand hebben gemaakt, moeten we ook bellen AssetDatabase.Refresh ()
, dus de eenheid is in staat om het te zien.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Assets", "Prefab Folder"); Object prefab = EditorUtility.CreateEmptyPrefab ("Assets / Prefab Folder / obj.prefab"); AssetDatabase.Refresh ();
Als we een constant pad als argument verlaten, zal elke keer dat we onze routine selecteren een nieuwe lege prefab de oude vervangen. Laten we elke prefab toewijzen aan een aparte map om dat tegen te gaan. Hiertoe moeten we de meest recent gemaakte map opslaan in een tekenreeks, zodat we deze later als padargument kunnen gebruiken. De Map aanmaken
functie retourneert a GUID
, die in feite de ID van het bestand (of de map) is. Er is een functie die het pad ophaalt als we dit ID verzenden. Het heet GUIDToAssetPath
; laten we het gebruiken om het pad van onze map te krijgen.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Assets", "Prefab Folder")); Object prefab = EditorUtility.CreateEmptyPrefab ("Assets / Prefab Folder / obj.prefab"); AssetDatabase.Refresh ();
Laten we nu de pad
om de prefabs die we gaan maken naar de laatst gemaakte map te leiden.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Assets", "Prefab Folder")); Object prefab = EditorUtility.CreateEmptyPrefab (path + "/obj.prefab"); AssetDatabase.Refresh ();
Je kunt testen of de gemaakte lege prefabs nu in mappen zijn ingepakt.
Als u een prefab maakt, wilt u deze waarschijnlijk niet leeg laten, omdat het in dat geval vrij nutteloos is. Laten we onze prefab instellen als er een game-object is geselecteerd terwijl onze routine wordt uitgevoerd. We zullen de prefab van het geselecteerde object maken. Om het momenteel geselecteerde object te krijgen, kunnen we de Selectie
klasse die ernaar verwijst. Om de prefab in te stellen moeten we bellen ReplacePrefab ()
.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Assets", "Prefab Folder")); Object prefab = EditorUtility.CreateEmptyPrefab (path + "/obj.prefab"); AssetDatabase.Refresh (); if (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab);
Als u de routine uitvoert met een willekeurig spelobject dat nu is geselecteerd, zult u merken dat het gemaakte prefab automatisch wordt ingesteld.
Dat is alles. We hebben een aangepaste routine gemaakt voor het maken van prefab. Het is niet erg handig, maar je moet nu weten hoe je dat moet doen als er zoiets in je project nodig is..
Aan het einde wil ik dat ook noemen AssetDatabase
laat je ook assets verplaatsen, verplaatsen naar de prullenbak of verwijderen door te bellen AssetDatabase.MoveAsset (), AssetDatabase.MoveAssetToTrash ()
en AssetDatabase.DeleteAsset ()
respectievelijk. De rest van de functionaliteit is te vinden op de AssetDatabase
script referentiepagina.
Laten we naar een ander voorbeeld gaan, deze keer zullen we een textuur en een materiaal programmatisch creëren. Laten we dit menu-item noemen Materiële routine.
[MenuItem ("Voorbeelden / Prefab-routine")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Assets", "Prefab Folder")); Object prefab = EditorUtility.CreateEmptyPrefab (path + "/obj.prefab"); AssetDatabase.Refresh (); if (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab); [MenuItem ("Examples / Material Routine")] static void MaterialRoutine ()
Nu hebben we twee items om uit te kiezen in de Voorbeelden menu.
Laten we een maken Texture2D
en stel de grootte in op (256, 256)
voor dit voorbeeld.
[MenuItem ("Examples / Material Routine")] static void MaterialRoutine () Texture2D tex = new Texture2D (256, 256);
Nu moeten we niet al die pixels laten verspillen, dus laten we de pixels van de textuur instellen volgens een soort van bedachte formule. Daar hebben we er twee nodig voor
loops om elke pixel te doorlopen. Om de kleur van elke pixel in te stellen, moeten we bellen SetPixel ()
die de positie van de pixel op een textuur en de kleur ervan als de argumenten neemt.
[MenuItem ("Examples / Material Routine")] static void MaterialRoutine () Texture2D tex = new Texture2D (256, 256); voor (int y = 0; y < 256; ++y) for (int x = 0; x < 256; ++x) tex.SetPixel(x, y, new Color());
Om de kleur toe te wijzen, gebruiken we de Mathf.Sin ()
functie. De Kleur
klasse kan worden geïnitialiseerd met drie drijvers, overeenkomend met respectievelijk de rode, groene en blauwe kleurcomponenten. De maximaal toegestane waarde is 1
en min is 0
, dus de Zonde()
functie past perfect bij onze behoeften.
voor (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)));
Het doet er niet toe wat we ons onderwerpen aan de Zonde()
functie, maar om iets interessants te krijgen, moeten we een waarde geven die voor elke pixel verandert.
Laten we nu een afbeelding maken van de textuur die we zojuist hebben gemaakt. Omdat we in binaire modus naar een bestand schrijven, moeten we dat ook zijn met behulp van System.IO
, dus laten we het aan de bovenkant van ons script toevoegen.
gebruikmakend van UnityEngine; met behulp van System.Collections; gebruikmakend van UnityEditor; met behulp van System.IO; openbare klasse Voorbeelden: Editor
Om onze textuur te bewaren als een PNG afbeelding die we eerst moeten bellen EncodeToPNG ()
die een reeks bytes zal teruggeven die de PNG bestand bestaat uit.
voor (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();
Nu dat we onze hebben pngData
we kunnen het naar een bestand schrijven en een maken PNG afbeelding op deze manier.
byte [] pngData = tex.EncodeToPNG (); if (pngData! = null) File.WriteAllBytes ("Assets / texture.png", pngData);
Omdat we het bestand op een constant pad maken, wordt elke keer dat we het uitvoeren MaterialRoutine ()
, de textuur wordt overschreven.
En aangezien we ons beeld hebben, hebben we de gegenereerde textuur niet meer nodig, omdat er toch niet naar een afbeelding wordt verwezen. Laten we het vernietigen.
byte [] pngData = tex.EncodeToPNG (); if (pngData! = null) File.WriteAllBytes ("Assets / texture.png", pngData); DestroyImmediate (tex);
Ook moeten we Unity de projectweergave en bestandsreferenties laten bijwerken; om dat te doen moeten we bellen AssetDatabase.Refresh ()
.
byte [] pngData = tex.EncodeToPNG (); if (pngData! = null) File.WriteAllBytes ("Assets / texture.png", pngData); DestroyImmediate (tex); AssetDatabase.Refresh ();
Laten we testen of de textuur wordt aangemaakt wanneer we onze routine uitvoeren.
We hebben een afbeelding en nu kunnen we een materiaal maken dat het als een textuur gebruikt. Laten we een maken nieuw materiaal
.
AssetDatabase.Refresh (); nieuw materiaal (Shader.Find ("Diffuus"));
Het gemaakte materiaal zal a gebruiken Diffuus shader. Om dit materiaal in het bestand op te slaan, kunnen we bellen AssetDatabase.CreateAsset ()
. Deze functie neemt een item als het eerste argument, en het pad als het tweede argument.
AssetDatabase.Refresh (); AssetDatabase.CreateAsset (nieuw materiaal (Shader.Find ("Diffuse")), "Assets / New Material.mat");
Als u nu onze routine uitvoert, ziet u dat het materiaal is gemaakt.
Zoals je kunt zien is alles correct, de naam is Nieuw materiaal en het gebruikt Diffuus shader, maar er is geen structuur aan toegewezen.
Eerst moeten we een verwijzing krijgen naar het materiaal dat we zojuist hebben gemaakt. Dat kunnen we krijgen door te bellen AssetDatabase.LoadAssetAtPath ()
die het item laadt en zijn referentie retourneert.
AssetDatabase.CreateAsset (nieuw materiaal (Shader.Find ("Diffuse")), "Assets / New Material.mat"); Materiaalmateriaal = (Materiaal) (AssetDatabase.LoadAssetAtPath ("Activa / Nieuw materiaal.mat", typeof (artikel)));
Laten we nu onze gegenereerde textuur toewijzen als de hoofdstructuur van het materiaal. We kunnen de textuurreferentie van de gegenereerde textuur op dezelfde manier krijgen als de materiaalreferentie.
Materiaalmateriaal = (Materiaal) (AssetDatabase.LoadAssetAtPath ("Activa / Nieuw materiaal.mat", typeof (artikel))); material.mainTexture = (Texture2D) (AssetDatabase.LoadAssetAtPath ("Assets / texture.png", typeof (Texture2D)));
Om de resultaten te zien, voert u de Materiële routine.
Zoals je ziet, heeft het materiaal nu de textuur toegewezen gekregen.
Dat is het einde van de introductie om uw bedrijfsmiddelen te beheren met behulp van scripts. Als u uw kennis over het onderwerp wilt uitbreiden, kunt u de Unity Editor Classes-verwijzingspagina bezoeken, met name de verwijzing naar het AssetDatabase-script is het waard om hiernaar te kijken. Als u op een laag niveau moet werken, lees dan ook de documentatie op System.IO voor meer informatie over de klassen en hoe u deze kunt gebruiken. Bedankt voor je tijd!