Så här anpassar du enhetligt spelobjekt med kod

I denna handledning visar jag dig grunderna i att använda procedurmässig objektanpassning till din fördel, i Unity. Det kokar i grunden till använda slumpmässighet inom vissa regler. Om du använder något slags procedursystem (till och med en enkel) kan du lägga till en mängd olika mångfald och detaljer i ditt spel utan att behöva skapa allt manuellt.

Vi börjar med att skapa ett enkelt träd manuellt och sedan använda procedur anpassningstekniker för att automatisera skapandet av en rad liknande men ändå olika träd. Sedan lägger vi dessa träd i ett enkelt spel för att visa hur de ser ut i "action".

Här är vad våra procedurgenererade träd kommer att se ut:


Klicka på knappen för att generera en ny uppsättning träd.

Inrätta

Som i min tidigare handledning måste du ha Unity installerat och ha grundläggande kunskaper om det. (Se hur man läser enighet för ett bra ställe att komma igång.)

Skapa ett nytt projekt för denna handledning och markera kryssrutan märkt karaktärsstyrare; vi kanske behöver dem senare.

Jag har förberett några träd som vi kommer att använda, som du kan hitta i 3d-filer mapp på källans nedladdning. Hela projektfilerna, om du vill använda dem, kan också hittas i källnedladdningen, men är inte nödvändiga för denna handledning.

Redo? Nu går vi!


Skapa ett träd

Låt oss skapa ett enkelt träd först eftersom vi behöver en grundläggande mall för att börja från, för att lägga till procedurberöringar.

Sätt de 3D-filer som jag nämnde ovan i aktivmappen. Kom ihåg att ställa in skalan i importören till 1 hellre än 0,001, så att storlekarna stämmer upp.

Skapa nu en kub och namnge den Träd. Gå till Mesh Filter komponent och byt ut kubenätet för tree_01 maska. Det borde dyka upp om du har 3D-filerna i din aktivmapp.

Träet kanske inte visas helt. Detta beror på att 3D-modellen för trädet stöder två material (bark och löv), men just nu är det fortfarande inställt på en. För att åtgärda detta, öppna material array i Mesh Renderer komponent i kuben och ställa in Storlek till 2. Det ska se ut så här:

Nu behöver vi material för bark och löv. Skapa två nya material och ge dem en grundläggande brun och grön färg. Tilldela dessa två material till material slot i Mesh Renderer av trädet, och det ska visas med de material som visas, så här:

För att avsluta detta grundläggande träd, lägg till en kapselkollider genom att klicka på Komponent> Fysik> Kapsel Collider. Det här är så att vi inte kommer att flytta "genom" trädet när vi testar det senare. Enhet kommer att fråga om du vill ersätta den aktuella rutkollideraren på trädet, vilket du bör bekräfta. När den nya colliden är tillsatt, ändra värdena så att kapselns form överlappar trädets stam, så här:

Dessa värden kommer att fungera:

Dra nu trädobjektet i projektmappen för att göra det till en prefab. Vårt grundläggande träd är gjort!


Slumpmässigt Rotating the Trees

Skapa ett nytt skript som heter tree.js och lägg till det i träprefabriken. Lägg nu följande rader till Start() fungera:

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

Träet kommer nu att roteras en slumpmässig mängd på y-axeln när den skapas. Detta innebär att om du lägger en rad träd, så här:

... då vänder de sig alla i sin egen riktning när de startar spelet. Sätt en massa träd i din nivå och prova det!


Justera storleken

På ett liknande sätt kan vi ändra storleken på något objekt. Lägg till följande kod till tree.js manus:

transform.localScale = transform.localScale * Random.Range (0,5, 1,5);

Detta kommer antingen att minska eller öka trädets storlek. Om du börjar med en skala av 1 (vilket borde vara fallet om allt är korrekt inställt) kommer den nya skalan att vara mellan 0,5 (halv så stor) och 1,5 (50% större). Nu bör dina träd se ännu mer olika ut:


Använda olika 3D-modeller

Du kanske har märkt att det faktiskt finns tre träd i de filer jag gav dig tidigare. Det beror på att vi nu slumpmässigt byter ut 3D-modellen för en annan och skapar ännu fler träd från mallen.

För att göra det, lägg till följande kod till tree.js manus:

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

Innan du börjar scenen, tilldela du de tre maskorna vi har till den uppsättningen, så här:

Om du spelar din scen märker du att du nu får tre olika trädmaskar, slumpmässigt tilldelade.

Du kan testa allt detta i demo nedan. Om du trycker på knappen kommer alla träd att ersättas med nya och unika.


Ändra färg

Det här kan vara lite knepigt. Förutom alla tidigare funktioner ger vi varje träd en unik nyans av grönt och brunt.

Först måste vi veta hur man får tillgång till färgerna. Materialet i ett föremål kan vanligtvis nås via renderer.material.color. I vårt fall har vi dock två färger, vilket innebär att vi behöver komma åt dem via renderer.materials [0] .color och renderer.materials [1] .color. Kontrollera trädets maskreverant för att se vilket material (löv eller bark) är i slitsen 0, och vilken är i slits 1.

Att skapa en slumpmässig färg fungerar på samma sätt som tidigare steg. Om du lägger till dessa rader:

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

... då får både barkmaterialet och bladmaterialet få en helt ny färg tilldelad. Låt oss kolla upp det:

Okej, det är inte vad vi faktiskt går för. Dessa är slumpmässiga färger från hela tillgängligt spektrum! För konstgjorda föremål, som bilar, kan det vara tillräckligt. Men vi har träd, så vi behöver gröna och bruna.

Ersätt den färgkod vi just har lagt till med detta:

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 = Färg (Random.Range (0, 0.4), Random.Range (0.6, 1.1), Random.Range (0, 0.4));

Och prova det:

Mycket bättre. (Om plötsligt bladen är bruna och stammen är grön, byt den 1 och 0 i renderer.materials [0].)

Koden skapar en ny färg i början av programfärgen. De tre slumpmässiga värdena går från 0 (minimum) till 1 (max), som då motsvarar de röda, gröna och blå värdena i färgen. Genom att begränsa slumpmässans intervall, som att säga Random.Range (0.3, 0.6), Värdena är begränsade till ett visst intervall. Detta gör det möjligt för oss att skapa en rad nya färger som fortfarande är "gröna", eller vilken färg vi kan ange.


Vinkla trädet (valfritt)

Detta är bara en liten tweak, men en trevlig en ändå. Vi kan ge trädet ett litet sned åt sidan, vilket eliminerar den "rena placeringen" känslan som kanske kommit upp tidigare

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

Den här gången appliceras en mycket liten rotation på x-axeln, vilket gör att trädet lutar sig i den riktningen. För att säkerställa att det inte finns något "gap" mellan trädets rötter och marken, är "svängningen" (eller mitten) av trädnätet något över rötterna, vilket betyder att det finns tillräckligt med wiggle-rum.

Hela trädskriptet ska se ut så här:

var treeMeshes: Mesh []; funktion 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 = Färg (Random.Range (0, 0.4), Random.Range (0.6, 1.1), Random.Range (0, 0.4)); 

Du kan prova allt i den här demo:


Skapa en enkel processnivå

Låt oss se hur dessa känns i ett verkligt spel.

Sätt ett plan på marken och skala upp det. Detta blir vår "golv" för nivån. Medan du är på det, skapa ett golvmaterial och tilldela det till golvet. Ställ in skalfaktorn för planet till 50.1.50, så vi har tillräckligt med utrymme.

Sätt sedan en första personkontrollant in i scenen. Den finns i de karaktärskontroller som importerades i början av handledningen. (Om du inte har dem klickar du på Tillgångar> Importpaket> Teckenstyrare). När du har placerat FPS-kontrollerna, ta bort huvudkameraet. styrenheten kommer med sin egen, så vi behöver inte kameran i scenen längre. Lägg också till ett riktrikt ljus.

För att automatiskt skapa träd skapar du en ny JavaScript-fil och heter den treeGenerator.js. Lägg följande kod i den:

var treePrefab: GameObject; var numberOfTrees: int = 20; funktion Start () för (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); 

Sätta treeGenerator.js skript på golvet, tilldela trädet prefab till treePrefab variabel plats och prova det:

Och gjort! Nu har du ett enkelt exploratory game, vilket kommer att skapa en unik nivå varje gång.

Ytterligare förbättringar

Spelet du har kan nu bli vildt utökat. Du kan lägga till fler växter, som palmer eller buskar. Du kan lägga till andra objekt, som stenar eller äpplen. Eller så kan du lägga till något slags mynt eller pickup, vilket spelaren kan springa över för att öka poängen.


Slutsats

Procedurella beröringar är ett enkelt och effektivt sätt att skapa detaljer automatiskt. I stället för att ha tio objekt kan du ha oändligt många.

Du kan använda de element som vi spelade med i din egen spel, eller du kan ta bort dem och skriva om dem så att de passar dina egna ändamål. Till exempel gjorde jag ett system som skapar olika längder av bambu:

Du kan göra bilar med olika element, eller placera automatiskt fiender på en nivå. Möjligheterna är oändliga.