Am analizat anterior adăugarea propriilor instrumente editorului Unity; acum, în acest tutorial scurt, vă prezint manipularea activelor prin script în Unity. Vom gestiona căile, vom crea fișiere prefabricate, vom genera textura și vom salva imaginea. În cele din urmă, vom crea și un fișier de material care utilizează imaginea generată și toate acestea vor fi realizate prin cod.
Să aruncăm o privire asupra rezultatului final pe care îl vom strădui:
Creați un proiect gol; nu vom folosi nimic fantezie aici, așa că nu ar trebui să ne deranjez să importăm nimic. După ce sa terminat, creați un script de editor. Unitatea ne va permite să folosim clasele editorului numai dacă plasăm scenariul într-un folder numit Editor. Din moment ce nu există încă în proiectul nostru, trebuie să-l creăm.
Acum, să creăm un scenariu în interiorul lui.
Să ne curățăm scenariul. În afară de funcționalitatea de bază, dorim, de asemenea, să folosim clasele editorilor. Trebuie să fim utilizând UnityEditor
iar clasa scriptului nostru ar trebui să extindă Editor
clasă în loc de MonoBehaviour
cum fac obiectele normale de joc.
utilizând UnityEngine; utilizând System.Collections; utilizând UnityEditor; clasa publica Exemple: Editor
În prima noastră funcție vom lucra cu prefabricate, să zicem a PrefabRoutine
.
clasa publică Exemple: Editor void PrefabRoutine ()
Pentru a executa cu ușurință această funcție din editor, să o adăugăm ca a Articol din meniu
.
clasa publica Exemple: Editor [MenuItem ("Exemple / Prefab Routine")] void PrefabRoutine ()
În afară de a lăsa unitatea să știe că vrem ca această funcție să fie executabilă de la Exemple-> Rutină prefabricată ", trebuie să facem și această funcție statică.
clasa publica Exemple: Editor [MenuItem ("Exemple / Prefab Routine")] static void PrefabRoutine ()
Dacă reveniți acum la editor (și reîmprospătați meniul), veți observa că există un nou meniu numit Exemple Acolo.
Dacă selectați Pregătire de rutină nimic nu se va întâmpla deoarece funcția noastră este goală.
Pentru a ne modela proiectul așa cum ne dorim, trebuie să știm cum să creăm foldere, astfel încât să putem muta chestii. Crearea unui dosar din script este foarte simplă, tot ce trebuie să facem este să lăsăm unitatea să știe unde trebuie să fie plasat dosarul. Pentru a crea un dosar, trebuie să îl folosim AssetDatabase
clasă.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Active", "Prefab Folder");
„Active“ este numele directorului părinte al directorului pe care dorim să-l creăm. În cazul nostru, este directorul principal al proiectului în care toate activele noastre sunt importate / create.
Rețineți că puteți utiliza și .NET Director
clasă. Acest lucru vă va permite să ștergeți, să mutați sau să accesați fișierele directoarelor. Pentru a folosi această clasă trebuie să fii folosind System.IO
.
De fiecare dată când selectați Pregătire de rutină din editor, trebuie creat un nou dosar și să fie vizibil în vizualizarea proiectului.
Pentru a crea un prefabricat trebuie să sunăm EditorUtility.CreateEmptyPrefab ()
. Funcția ia calea prefabricatului ca argument.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Active", "Prefab Folder"); Object prefab = EditorUtility.CreateEmptyPrefab ("Active / Prefab Folder / obj.prefab");
Nu uitați de prelungire! De asemenea, după ce vom crea fișierul, trebuie să sunăm AssetDatabase.Refresh ()
, astfel încât unitatea este capabilă să o vadă.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () AssetDatabase.CreateFolder ("Active", "Prefab Folder"); Object prefab = EditorUtility.CreateEmptyPrefab ("Active / Prefab Folder / obj.prefab"); AssetDatabase.Refresh ();
Dacă lăsăm o cale constantă ca argument, de fiecare dată când alegem rutina noastră, un nou prefabricat gol va înlocui cel vechi. Să atribuim fiecărui prefab un folder separat pentru a contracara acest lucru. Pentru a face acest lucru trebuie să salvăm cel mai recent dosar creat într-un șir, astfel încât îl putem folosi mai târziu ca argument de cale. Creeaza dosar
funcția returnează a GUID
, care este în esență ID-ul fișierului (sau directorului). Există o funcție care recuperează calea dacă trimitem acest ID. Se numeste GUIDToAssetPath
; să o folosim pentru a obține calea dosarului nostru.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Active", "Prefab Folder")); Object prefab = EditorUtility.CreateEmptyPrefab ("Active / Prefab Folder / obj.prefab"); AssetDatabase.Refresh ();
Acum să folosim cale
pentru a direcționa prefabricatele pe care le vom crea în cel mai recent dosar creat.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Active", "Prefab Folder")); Obiect prefab = editorUtility.CreateEmptyPrefab (calea + "/obj.prefab"); AssetDatabase.Refresh ();
Puteți testa dacă prefabricatele create goale sunt împachetate acum în foldere.
Dacă creați un prefabricat, probabil că nu doriți să îl lăsați gol, deoarece în acest caz este aproape inutil. Să ne setăm prefabricatul dacă există un obiect de joc selectat în timp ce rutina noastră este executată. Vom prefabrica obiectul selectat. Pentru a obține obiectul selectat curent, putem folosi Selecţie
clasa care are o referință la ea. Pentru a seta prefabricatul trebuie să sunăm ReplacePrefab ()
.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Active", "Prefab Folder")); Obiect prefab = editorUtility.CreateEmptyPrefab (calea + "/obj.prefab"); AssetDatabase.Refresh (); dacă (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab);
Dacă executați rutina cu orice obiect de joc selectat acum, atunci veți observa că prefabricatul creat este setat automat.
Asta e, am creat o rutină personalizată pentru crearea de prefaburi, nu este foarte utilă, dar ar trebui să știi cum să faci asta acum dacă va fi nevoie de un astfel de lucru în proiectul tău.
La final, vreau să menționez și asta AssetDatabase
vă permite să mutați în jurul valorii de bunuri, să le mutați în coșul de gunoi sau să le ștergeți prin apelare AssetDatabase.MoveAsset (), AssetDatabase.MoveAssetToTrash ()
și AssetDatabase.DeleteAsset ()
respectiv. Restul funcționalității poate fi găsită la AssetDatabase
script de referință.
Să mergem la un alt exemplu, de data aceasta vom crea o textură și un material programat. Să sunăm acest element din meniu Materiale de rutină.
[MenuItem ("Exemple / Rutină prefabricată")] static void PrefabRoutine () string path = AssetDatabase.GUIDToAssetPath (AssetDatabase.CreateFolder ("Active", "Prefab Folder")); Obiect prefab = editorUtility.CreateEmptyPrefab (calea + "/obj.prefab"); AssetDatabase.Refresh (); dacă (Selection.activeObject) EditorUtility.ReplacePrefab (Selection.activeGameObject, prefab); [MenuItem ("Exemple / Material Routine")] static void MaterialRoutine ()
Acum avem două elemente de a alege din Exemple meniul.
Să creăm a Texture2D
și setați dimensiunea acesteia la (256, 256)
pentru acest exemplu.
[MenuItem ("Exemple / Material Routine")] static void MaterialRoutine () Texture2D tex = Textură nouă (256, 256);
Acum nu ar trebui să lăsăm toți acei pixeli să se deterioreze, deci să setăm pixelii texturii conform unei formule de gândire. Pentru asta avem nevoie de două pentru
bucle pentru a trece prin fiecare pixel. Pentru a seta culoarea fiecărui pixel trebuie să sunăm SetPixel ()
care ia poziția pixelului pe o textura și culoarea sa ca argumente.
[MenuItem ("Exemple / Material Routine")] static void MaterialRoutine () Texture2D tex = Textură nouă (256, 256); pentru (int y = 0; y < 256; ++y) for (int x = 0; x < 256; ++x) tex.SetPixel(x, y, new Color());
Pentru a atribui culoarea, vom folosi Mathf.Sin ()
funcţie. Culoare
clasa poate fi inițializată cu trei flotoare, corespunzătoare componentelor de culoare roșie, verde și albastră. Valoarea maximă permisă este 1
și min este 0
, asa ca Păcat()
funcția noastră se potrivește perfect nevoilor noastre.
pentru (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)));
Nu contează ce prezentăm Păcat()
funcția, dar pentru a obține ceva mai interesant ar trebui să oferim o valoare care se schimbă pentru fiecare pixel.
Acum, să creăm o imagine din textura pe care tocmai am creat-o. Deoarece vom scrie un fișier în modul binar, trebuie să fim folosind System.IO
, astfel încât să o adăugăm la partea de sus a scenariului nostru.
utilizând UnityEngine; utilizând System.Collections; utilizând UnityEditor; utilizând System.IO; clasa publică Exemple: Editor
Pentru a salva textura noastră ca a PNG imagine pe care trebuie să o apelăm mai întâi EncodeToPNG ()
care va returna o serie de octeți care PNG fișierul constă din.
pentru (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();
Acum că avem pe noi pngData
îl putem scrie într-un fișier și îl putem crea PNG imagine în acest fel.
octet [] pngData = tex.EncodeToPNG (); dacă (pngData! = null) File.WriteAllBytes ("Active / texture.png", pngData);
Din moment ce creăm fișierul pe o cale constantă, de fiecare dată când vom rula MaterialRoutine ()
, textura va fi suprascrisă.
Și din moment ce avem imaginea noastră, nu mai avem nevoie de textura generată, deoarece oricum nu va face referire la o imagine. Să o distrugem.
octet [] pngData = tex.EncodeToPNG (); dacă (pngData! = null) File.WriteAllBytes ("Active / texture.png", pngData); DestroyImmediate (tex);
De asemenea, trebuie să lăsăm Unity să actualizeze vizualizarea proiectului și referințele fișierelor; pentru a face asta trebuie să sunăm AssetDatabase.Refresh ()
.
octet [] pngData = tex.EncodeToPNG (); dacă (pngData! = null) File.WriteAllBytes ("Active / texture.png", pngData); DestroyImmediate (tex); AssetDatabase.Refresh ();
Să testați dacă textura este creată atunci când executăm rutina noastră.
Avem o imagine și acum putem crea un material care o folosește ca textura. Să creăm a material nou
.
AssetDatabase.Refresh (); material nou (Shader.Find ("Diffuse"));
Materialul creat va folosi a Difuz shader. Pentru a salva acest material în fișier, putem apela AssetDatabase.CreateAsset ()
. Această funcție are un element ca primul argument, iar calea ca al doilea.
AssetDatabase.Refresh (); AssetDatabase.CreateAsset (material nou (Shader.Find ("Diffuse")), "Active / New Material.mat");
Dacă rulați rutina noastră acum, veți vedea că materialul este creat.
După cum puteți vedea totul corect, numele său este Material nou și folosește Difuz shader, dar nu i se atribuie nici o textura.
Mai întâi trebuie să facem referire la materialul pe care tocmai l-am creat. Putem obține asta prin chemare AssetDatabase.LoadAssetAtPath ()
care încarcă materialul și returnează referința acestuia.
AssetDatabase.CreateAsset (material nou (Shader.Find ("Diffuse")), "Active / New Material.mat"); Material material = (Material) (AssetDatabase.LoadAssetAtPath ("Active / New Material.mat", typeof (Material)));
Acum, să alocăm textura generată ca textura principală a materialului. Putem obține referința texturii texturii generate în același mod în care obținem referința materialului.
Material material = (Material) (AssetDatabase.LoadAssetAtPath ("Active / New Material.mat", typeof (Material))); material.mainTexture = (Texture2D) (AssetDatabase.LoadAssetAtPath ("Active / texture.png", typeof (Texture2D)));
Pentru a vedea rezultatele, rulați Materiale de rutină.
După cum puteți vedea, materialul are textura atribuită acum.
Acesta este sfârșitul introducerii pentru a gestiona activele folosind scripturi. Dacă doriți să vă extindeți cunoștințele despre subiect, puteți vizita pagina de referință Unity Editor Classes, în special referința scriptului AssetDatabase. Dacă trebuie să lucrați la un nivel scăzut, ar trebui să citiți documentele de pe System.IO pentru a obține mai multe informații despre clasele sale și cum le puteți folosi. Mulțumesc pentru timpul acordat!