Hoe u uw Unity-spelactiva procedureel aanpast met code

In deze tutorial laat ik u de basis zien van het gebruik van procedurele objectaanpassing in uw voordeel, in Unity. Het komt er eigenlijk op neer gebruik van willekeur binnen bepaalde regels. Als je een soort van procedureel systeem gebruikt (zelfs een eenvoudig procedé), kun je een breed scala aan diversiteit en details aan je spel toevoegen zonder het allemaal handmatig te hoeven maken.

We zullen beginnen met het handmatig aanmaken van een eenvoudige boom en vervolgens procedurele aanpassingsmethoden gebruiken om het creëren van een reeks vergelijkbare maar met name verschillende bomen te automatiseren. Vervolgens plaatsen we deze bomen in een eenvoudig spel, om te laten zien hoe ze eruit zien in "actie".

Dit is wat onze procedureel gegenereerde bomen eruit zullen zien:


Klik op de knop om een ​​nieuwe set bomen te genereren.

Opstelling

Net als in mijn vorige zelfstudie moet Unity zijn geïnstalleerd en een basiskennis hiervan hebben. (Zie Eenheid leren voor een goede plek om aan de slag te gaan.)

Maak een nieuw project voor deze zelfstudie en vink het selectievakje aan karaktercontrollers; we hebben ze misschien later nodig.

Ik heb wat bomen klaargemaakt die we zullen gebruiken, die je kunt vinden in de 3D-bestanden map van de brondownload. De volledige projectbestanden, voor het geval u ze wilt gebruiken, zijn ook te vinden in de brondownload, maar zijn niet noodzakelijk voor deze zelfstudie.

Klaar? Laten we gaan!


Een boom maken

Laten we eerst een eenvoudige boom maken. Om procedurele details toe te voegen, hebben we een basissjabloon nodig om van te beginnen.

Zet de 3D-bestanden die ik hierboven noemde in de activamap. Vergeet niet om de schaal in de importeermachine in te stellen 1 liever dan 0.001, zodat de maten op een rij staan.

Maak nu een kubus en noem die Boom. Ga naar de Mesh Filter component en verwissel het kubusnet voor de tree_01 mesh. Het zou moeten verschijnen als u de 3D-bestanden in uw activamap hebt.

De boom is misschien nog niet helemaal zichtbaar. Dit komt omdat het 3D-model voor de boom twee materialen ondersteunt (schors en bladeren), maar nu is het nog steeds ingesteld op één. Om dit op te lossen, opent u de materialen array in de Mesh Renderer component van de kubus, en stel de Grootte naar 2. Het zou er zo uit moeten zien:

Nu hebben we materialen nodig voor de schors en bladeren. Maak twee nieuwe materialen en geef ze een eenvoudige bruine en groene kleur. Ken deze twee materialen toe aan de materialen slot in de Mesh Renderer van de boom, en het zou moeten verschijnen met de weergegeven materialen, zoals dit:

Om deze basisboom af te werken, voegt u een capsule-collider toe door op te klikken Component> Fysica> Capsule Collider. Dit is zodat we niet "door" de boom zullen bewegen als we het later testen. Unity zal u vragen of u de huidige box-collider in de boom wilt vervangen, die u moet bevestigen. Nadat de nieuwe collider is toegevoegd, wijzigt u de waarden zodat de vorm van de capsule ongeveer de stam van de boom overlapt, zoals:

Deze waarden werken:

Trek nu het tree-object in de projectmap om er een prefab van te maken. Onze basisboom is klaar!


Willekeurig roteren van de bomen

Maak een nieuw script met de naam tree.js en voeg het toe aan de boom prefab. Voeg nu de volgende regels toe aan de Begin() functie:

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

De boom zal nu willekeurig worden geroteerd op de y-as wanneer deze wordt gemaakt. Dit betekent dat als je een rij bomen plaatst, zoals deze:

... dan draaien ze allemaal hun eigen richting na het starten van het spel. Zet een aantal bomen in je level en probeer het uit!


De grootte aanpassen

Op een vergelijkbare manier kunnen we de grootte van elk object wijzigen. Voeg de volgende code toe aan de tree.js script:

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

Dit zal de boom verkleinen of vergroten. Als u begint met een schaal van 1 (wat het geval zou moeten zijn als alles correct is ingesteld), zal de nieuwe schaal tussen 0,5 (half zo groot) en 1,5 (50% groter) zijn. Nu zouden je bomen er nog diverser uit moeten zien:


Verschillende 3D-modellen gebruiken

Je hebt misschien gemerkt dat er drie bomen in de bestanden staan ​​die ik je eerder heb gegeven. Dat komt omdat we nu willekeurig het 3D-model voor een ander model schakelen, waardoor er nog meer bomen uit de sjabloon worden gemaakt.

Voeg hiervoor de volgende code toe aan de tree.js script:

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

Voordat we de scène beginnen, wijs je de drie meshes toe die we hebben aan die array, zoals deze:

Als je je scène afspeelt, zul je merken dat je nu drie verschillende boom-mazen krijgt, willekeurig toegewezen.

Je kunt dit alles testen in de demo hieronder. Als je op de knop drukt, worden alle bomen vervangen door nieuwe en unieke bomen.


De kleur veranderen

Deze is misschien een beetje lastig. Naast alle voorgaande functies, geven we elke boom een ​​unieke tint groen en bruin.

Ten eerste moeten we weten hoe toegang te krijgen tot de kleuren. Het materiaal van een object is meestal toegankelijk via renderer.material.color. In ons geval hebben we echter twee kleuren, wat betekent dat we ze moeten benaderen via renderer.materials [0] .Kleur en renderer.materials [1] .Kleur. Controleer de mesh-renderer van de boom om te zien welk materiaal (bladeren of schors) zich in slot 0 bevindt en welke zich in sleuf 1 bevindt.

Het maken van een willekeurige kleur werkt op dezelfde manier als de vorige stappen. Als u deze regels toevoegt:

renderer.materials [0] .color = Color (Random.Range (0, 1.1), Random.Range (0, 1.1), Random.Range (0, 1.1)); renderer.materials [1] .color = Color (Random.Range (0, 1.1), Random.Range (0, 1.1), Random.Range (0, 1.1));

... dan krijgen zowel het schorsmateriaal als het bladmateriaal een geheel nieuwe kleur toegewezen. Laten we het bekijken:

Oké, dat is niet waar we voor gaan. Dit zijn willekeurige kleuren uit het gehele beschikbare spectrum! Voor kunstmatige items, zoals auto's, is dit misschien genoeg. Maar we hebben bomen, dus we hebben groen en bruin nodig.

Vervang de kleurcode die we zojuist hebben toegevoegd hiermee:

renderer.materials [0] .color = Color (Random.Range (0.8, 1.1), Random.Range (0.4, 0.6), Random.Range (0, 0.2)); renderer.materials [1] .color = Color (Random.Range (0, 0.4), Random.Range (0.6, 1.1), Random.Range (0, 0.4));

En probeer het uit:

Veel beter. (Als plotseling de bladeren bruin zijn en de stam groen is, verwisselt u de 1 en 0 in renderer.materials [0].)

De code produceert een nieuwe kleur aan het begin van de programmeerkleur. De drie willekeurige waarden gaan van 0 (minimum) naar 1 (maximum), die dan overeenkomt met de rode, groene en blauwe waarden in de kleur. Door het bereik van de willekeur te beperken, bijvoorbeeld door te zeggen Random.Range (0.3, 0.6), de waarden zijn beperkt tot een bepaald bereik. Dit stelt ons in staat een reeks nieuwe kleuren te creëren die nog "groen" zijn, of welke kleur we ook zouden kunnen specificeren.


De boom laten kantelen (optioneel)

Dit is slechts een kleine aanpassing, maar toch een leuke. We kunnen de boom een ​​beetje schuin naar één kant laten schijnen, waardoor het "net geplaatste" gevoel dat misschien eerder is ontstaan, wordt geëlimineerd

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

Deze keer wordt een zeer kleine rotatie toegepast op de x-as, waardoor de boom in die richting schuin staat. Om ervoor te zorgen dat er geen "opening" is tussen de wortels van de boom en de grond, is het "draaipunt" (of het midden) van de boommazen enigszins boven de wortels, wat betekent dat er voldoende bewegingsruimte beschikbaar is.

Het volledige boesscript zou er als volgt uit moeten zien:

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 = Color (Random.Range (0.8, 1.1), Random.Range (0.4, 0.6), Random.Range (0, 0.2)); renderer.materials [1] .color = Color (Random.Range (0, 0.4), Random.Range (0.6, 1.1), Random.Range (0, 0.4)); 

Je kunt het allemaal proberen in deze demo:


Een eenvoudig procesniveau creëren

Laten we eens kijken hoe deze zich voelen in een echt spel.

Leg een vliegtuig op de grond en hef het op. Dit zal onze "vloer" voor het niveau zijn. Terwijl je bezig bent, maak een vloermateriaal en wijs het toe aan de vloer. Stel de schaalfactor van het vlak in 50.1.50, dus we hebben genoeg ruimte.

Plaats vervolgens een first-person-controller in de scene. Het is te vinden in de tekenbesturingsprogramma's die aan het begin van de zelfstudie zijn geïmporteerd. (Als u ze niet hebt, klikt u op Activa> Importpakket> Tekencontrollers). Nadat u de FPS-controllers hebt geplaatst, verwijdert u de hoofdcamera; de controller heeft een eigen controller, dus we hebben de camera niet meer nodig in de scene. Voeg ook een gericht licht toe.

Als u automatisch bomen wilt maken, maakt u een nieuw JavaScript-bestand en geeft u dit een naam treeGenerator.js. Plaats de volgende code erin:

var treePrefab: GameObject; var numberOfTrees: int = 20; functie Start () voor (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); 

Zet de treeGenerator.js script op de grond, wijs de prefab boom toe aan de treePrefab variabele slot, en probeer het uit:

En klaar! Nu heb je een eenvoudig verkennend spel, dat elke run een uniek niveau zal creëren.

Verdere verbeteringen

Het spel dat je hebt, kan nu wild worden uitgebreid. Je zou meer planten kunnen toevoegen, zoals palmbomen of struiken. U kunt andere objecten toevoegen, zoals rotsen of appels. Of je kunt een soort muntstuk of elementen toevoegen, die de speler zou kunnen overreden om zijn score te verhogen.


Conclusie

Procedurele aanrakingen zijn een eenvoudige en efficiënte manier om automatisch details te creëren. In plaats van tien objecten te hebben, zou je kunnen hebben oneindig veel.

Je kunt de elementen gebruiken waarmee we in je eigen spel hebben gespeeld, of je kunt ze uit elkaar halen en ze opnieuw schrijven om je eigen doelen te bereiken. Ik heb bijvoorbeeld een systeem gemaakt dat verschillende lengtes van bamboe maakt:

Je kunt auto's maken met variabele elementen, of automatisch vijanden op een niveau plaatsen. De mogelijkheden zijn eindeloos.