{"id":33833,"date":"2025-08-13T11:55:47","date_gmt":"2025-08-13T09:55:47","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=33833"},"modified":"2025-08-13T11:55:48","modified_gmt":"2025-08-13T09:55:48","slug":"le-basi-della-generazione-procedurale-di-terreno-in-unity","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/","title":{"rendered":"Le basi della generazione procedurale di terreno in Unity"},"content":{"rendered":"\n<p>Nel contesto del game developement, la generazione procedurale del terreno \u00e8 una tecnica che utilizza <strong>algoritmi specifici per creare automaticamente ambienti di gioco<\/strong> (montagne, colline, isole&#8230;) in modo <strong>dinamico<\/strong>, ovvero senza che gli sviluppatori debbano realizzarli a mano.<\/p>\n\n\n\n<p>La generazione procedurale \u00e8 particolarmente comuni in giochi in cui si vuole fare in modo che il giocatore viva un&#8217;<strong>esperienza diversa ad ogni partita<\/strong>. \u00c8 infatti molto comune in quei videogiochi in cui il gameplay \u00e8 incentrato sull&#8217;esplorazione, la rigiocabilit\u00e0, la scoperta e la variet\u00e0 del mondo di gioco. Essa non \u00e8 limitata solo al terreno o al mondo di gioco, ma pu\u00f2 anche essere estesa a grafiche, effetti sonori, animazioni, questlines e molto altro.<\/p>\n\n\n\n<p>In questo articolo cerchiamo di capire meglio come funziona la generazione procedurale del terreno, osservando un esempio funzionante realizzato in <strong>Unity<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-dfc0c644\"><h2 class=\"uagb-heading-text\">Il funzionamento di un generatore procedurale, ad alto livello<\/h2><\/div>\n\n\n\n<p>Un generatore procedurale per un mondo di gioco \u00e8 essenzialmente un algoritmo che prende in input un numero intero, detto <strong>seed<\/strong>, e eventualmente altri parametri utili, e genera il mondo di gioco in maniera automatica sulla base dei parametri passati e del seed.<\/p>\n\n\n\n<p>Il seed \u00e8 utilizzato per garantire che il mondo sia generato in maniera <strong>deterministica<\/strong>: a parit\u00e0 di seed e parametri, il mondo generato dall&#8217;algoritmo sar\u00e0 sempre identico.<\/p>\n\n\n\n<p>Il seed \u00e8 infatti utilizzato per inizializzare uno o pi\u00f9 <strong>generatori di numeri pseudo-casuali<\/strong>, che, in quanto tali, generano numeri che sembrano casuali, ma che sono in realt\u00e0 completamente deterministici. Attraverso lunghe serie di trasformazioni, questi dati determinano la struttura del mondo di gioco.<\/p>\n\n\n\n<p>Questo pu\u00f2 non sembrare molto interessante, ma offre in realt\u00e0 un grande vantaggio: un mondo generato proceduralmente <strong>non ha bisogno di essere memorizzato localmente<\/strong>. Questo significa che anche mondi di dimensioni &#8220;infinite&#8221; sono tranquillamente realizzabili e riproducibili.<\/p>\n\n\n\n<p>Vediamo allora pi\u00f9 nel dettaglio una semplice implementazione per un generatore procedurale per il terreno di un generico mondo di gioco.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-perlin-noise-che-cos-e-e-come-funziona\">Perlin noise &#8211; che cos&#8217;\u00e8 e come funziona<\/h2>\n\n\n\n<p>Il <strong>Perlin noise<\/strong> \u00e8 un tipo di rumore sviluppato da <strong>Ken Perlin<\/strong> nel 1983. Si tratta di una funzione pseudo-casuale che restituisce valori numerici compresi tra -1 e 1 che variano in maniera <strong>graduale<\/strong> e &#8220;naturale&#8221; tra loro.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"1000\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1.png\" alt=\"Immagine del Perlin noise in due dimensioni.\" class=\"wp-image-33786\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1.png 1000w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1-300x300.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1-150x150.png 150w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1-768x768.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1-100x100.png 100w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-1-600x600.png 600w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><figcaption class=\"wp-element-caption\">Rappresentazione grafica del Perlin noise bidimensionale (normalizzato): le zone scure corrispondono a zone con valori prossimi allo zero, quelle chiare a zone con valori prossimi a 1.<\/figcaption><\/figure>\n\n\n\n<p>Il Perlin noise \u00e8 implementato creando una griglia sui cui vertici vengono definiti dei vettori di lunghezza unitaria con direzione scelta in maniera pseudo-casuale. Questi vettori sono detti &#8220;<strong>gradienti<\/strong>&#8220;.<\/p>\n\n\n\n<p>Per ogni singolo punto all&#8217;interno della griglia si calcola poi il <strong>vettore di offset<\/strong> rispetto ai vertici della cella della griglia in cui si trova il punto (che in 2D sono 4).<\/p>\n\n\n\n<p>Si calcola poi il prodotto scalare tra i vettori di offset e i gradienti dei rispettivi vertici. Si ottengono cos\u00ec degli scalari che sono poi &#8220;fusi&#8221; insieme tramite <strong>interpolazione<\/strong>, ottenendo il risultato sopra.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-perlin-noise-utilizzi\">Perlin noise &#8211; utilizzi<\/h2>\n\n\n\n<p>La maggior parte dei game engine mettono a disposizione funzioni come il Perlin noise pronte per l&#8217;uso. Tipicamente l&#8217;output di queste funzioni \u00e8 normalizzato nel <strong>range 0-1<\/strong>.<\/p>\n\n\n\n<p>Unity, ad esempio, mette a disposizione la funzione  <code>PerlinNoise<\/code> nella classe <code>Mathf<\/code>, definita come:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> float PerlinNoise(float x, float y);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Questa funzione prende in input i punti di sample <code>x<\/code> e <code>y<\/code>, da cui sar\u00e0 calcolato il valore in output.<\/p>\n\n\n\n<p>La chiave di moltissimi algoritmi di generazione procedurale del terreno \u00e8 utilizzare il valore in output dal Perlin noise come <strong>offset verticale per i vertici di un piano<\/strong>.<\/p>\n\n\n\n<p>Possiamo infatti costruire un piano <strong>suddiviso tante volte<\/strong> in modo da essere costituito da tante celle della stessa dimensione allineate a formare una griglia. Calcolando il Perlin noise <strong>in corrispondenza delle coordinate dei vertici della griglia<\/strong>, otteniamo un valore per ciascun vertice. Questo valore \u00e8 utilizzato per determinare <strong>di quanto alzare il vertice<\/strong> da cui \u00e8 stato calcolato.<\/p>\n\n\n\n<p>In questo modo il Perlin noise viene &#8220;proiettato&#8221; sul terreno, alzandolo e facendogli assumere una <strong>forma ondulatoria<\/strong>, simile a un paesaggio collinare.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p><em>Si noti che il metodo <code>Mathf.PerlinNoise<\/code> offerto da Unity \u00e8 una funzione deterministica: dato lo stesso input, restituisce sempre lo stesso valore, ma non consente di specificare un seed in maniera diretta, perch\u00e9 non si basa su un generatore di numeri pseudo-casuali interno.<\/em><\/p>\n\n\n\n<p><em>\u00c8 comunque possibile simulare un comportamento simile al seed introducendo un offset costante nelle coordinate di input. Ad esempio, usando <code>x + seedOffsetX<\/code> e <code>y + seedOffsetY<\/code>, \u00e8 possibile ottenere varianti del terreno generate in modo consistente a partire da un seed arbitrario.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-generazione-della-mesh\">Generazione della mesh<\/h2>\n\n\n\n<p>Per questo esempio rimaniamo su qualcosa di molto semplice. La prima cosa da fare \u00e8 costruire la mesh di partenza che poi deformeremo utilizzando il Perlin noise.<\/p>\n\n\n\n<p>La mesh in questione non \u00e8 altro che un piano suddiviso un certo numero di volte.<\/p>\n\n\n\n<p>Definiamo allora due variabili:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Scale<\/code>: specifica la dimensione del piano (per questo esempio supponiamo di forma quadrata)<\/li>\n\n\n\n<li><code>Resolution<\/code>: il numero di suddivisioni del piano<\/li>\n<\/ul>\n\n\n\n<p>In Unity una mesh \u00e8 definita da 3 ingredienti:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un array di <code>Vector3<\/code> (vertices), che rappresentano i <strong>vertici <\/strong>della mesh<\/li>\n\n\n\n<li>Un array di <code>int<\/code> (triangles), che rappresentano i <strong>triangoli <\/strong>di cui \u00e8 costituita la mesh<\/li>\n\n\n\n<li>Un array di <code>Vector2<\/code> (uvs), che rappresenta la <strong>mappa uv <\/strong>della mesh<\/li>\n<\/ul>\n\n\n\n<p>La generazione procedurale e l&#8217;interazione con ambienti di gioco generati proceduralmente funziona quasi sempre operando su questi dati. Il codice per generare il piano \u00e8 il seguente:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">using<\/span> System;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>&#91;<span class=\"hljs-meta\">ExecuteInEditMode<\/span>]\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">worldGenerator<\/span> : <span class=\"hljs-title\">MonoBehaviour<\/span>\n<\/span><\/span><span class='shcb-loc'><span>{\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> scale = <span class=\"hljs-number\">20<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> resolution = <span class=\"hljs-number\">10<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Awake<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    {\n<\/span><\/span><span class='shcb-loc'><span>        Generate();\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">OnValidate<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    {\n<\/span><\/span><span class='shcb-loc'><span>        Generate();\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Generate<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    {\n<\/span><\/span><span class='shcb-loc'><span>        Mesh mesh = <span class=\"hljs-keyword\">new<\/span> Mesh();\n<\/span><\/span><span class='shcb-loc'><span>        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">int<\/span> vertexCount = (resolution + <span class=\"hljs-number\">1<\/span>) * (resolution + <span class=\"hljs-number\">1<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>        Vector3&#91;] vertices = <span class=\"hljs-keyword\">new<\/span> Vector3&#91;vertexCount];\n<\/span><\/span><span class='shcb-loc'><span>        Vector2&#91;] uvs = <span class=\"hljs-keyword\">new<\/span> Vector2&#91;vertexCount];\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> y = <span class=\"hljs-number\">0<\/span>; y &lt;= resolution; y++)\n<\/span><\/span><span class='shcb-loc'><span>        {\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> x = <span class=\"hljs-number\">0<\/span>; x &lt;= resolution; x++)\n<\/span><\/span><span class='shcb-loc'><span>            {\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-keyword\">int<\/span> index = x + y * (resolution + <span class=\"hljs-number\">1<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>                Vector2 normalizedPosition = <span class=\"hljs-keyword\">new<\/span> Vector2((<span class=\"hljs-keyword\">float<\/span>)x \/ resolution, (<span class=\"hljs-keyword\">float<\/span>)y \/ resolution);\n<\/span><\/span><span class='shcb-loc'><span>                Vector2 worldPosition = normalizedPosition * scale;\n<\/span><\/span><span class='shcb-loc'><span>                vertices&#91;index] = <span class=\"hljs-keyword\">new<\/span> Vector3(worldPosition.x, <span class=\"hljs-number\">0f<\/span>, worldPosition.y);\n<\/span><\/span><span class='shcb-loc'><span>                uvs&#91;index] = <span class=\"hljs-keyword\">new<\/span> Vector2(normalizedPosition.x, normalizedPosition.y);\n<\/span><\/span><span class='shcb-loc'><span>            }\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">int<\/span>&#91;] triangles = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#91;resolution * resolution * <span class=\"hljs-number\">6<\/span>];\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> y = <span class=\"hljs-number\">0<\/span>; y &lt; resolution; y++)\n<\/span><\/span><span class='shcb-loc'><span>        {\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> x = <span class=\"hljs-number\">0<\/span>; x &lt; resolution; x++)\n<\/span><\/span><span class='shcb-loc'><span>            {\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-keyword\">int<\/span> vertexIndex = x + y * (resolution + <span class=\"hljs-number\">1<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i] = vertexIndex;\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i + <span class=\"hljs-number\">1<\/span>] = vertexIndex + resolution + <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i + <span class=\"hljs-number\">2<\/span>] = vertexIndex + <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i + <span class=\"hljs-number\">3<\/span>] = vertexIndex + <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i + <span class=\"hljs-number\">4<\/span>] = vertexIndex + resolution + <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>                triangles&#91;i + <span class=\"hljs-number\">5<\/span>] = vertexIndex + resolution + <span class=\"hljs-number\">2<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>                i += <span class=\"hljs-number\">6<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>            }\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>        mesh.vertices = vertices;\n<\/span><\/span><span class='shcb-loc'><span>        mesh.triangles = triangles;\n<\/span><\/span><span class='shcb-loc'><span>        mesh.uv = uvs;\n<\/span><\/span><span class='shcb-loc'><span>        mesh.RecalculateNormals();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>        GetComponent&lt;MeshFilter&gt;().mesh = mesh;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Con questo codice:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Specifichiamo la posizione dei vertici disponendoli su una griglia quadrata che copre l&#8217;intero piano.<\/li>\n\n\n\n<li>Specifichiamo gli uv <strong>normalizzando le coordinate dei vertici<\/strong>.<\/li>\n\n\n\n<li>Definiamo i triangoli che costituiscono la mesh indicando <strong>come connettere i vari vertici tra loro<\/strong> per formare ogni singolo triangolo. <\/li>\n\n\n\n<li>Assegnamo i dati cos\u00ec prodotti alla mesh creata e la associamo al MeshFilter dell&#8217;oggetto su cui stiamo lavorando.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-applichiamo-il-perlin-noise\">Applichiamo il Perlin noise<\/h2>\n\n\n\n<p>A questo punto possiamo applicare il Perlin noise. Per prima cosa, deformiamo la mesh usando Mathf.PerlinNoise: ci basta specificare come coordinata y nella definizione dei vertici il valore in output dal Perlin noise calcolato in corrispondenza di ciascun vertice:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">vertices&#91;index] = <span class=\"hljs-keyword\">new<\/span> Vector3(worldPosition.x, Mathf.PerlinNoise(normalizedPosition.x, normalizedPosition.y), worldPosition.y);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Con questa modifica il piano viene <strong>deformato<\/strong> a tutti gli effetti, ma di poco: <code>Mathf.PerlinNoise<\/code> restituisce infatti valori compresi tra 0 e 1. Possiamo definire una variabile <code>height<\/code> da usare per scalarne il risultato e avere cos\u00ec una deformazione maggiore. Per comodit\u00e0, definiamo anche una funzione <code>getElevation(float x, float y)<\/code> che ritorni la y da assegnare a ciascun vertice. La logica di generazione sar\u00e0 specificata al suo interno.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">float getElevation(float x , float y) {\n    <span class=\"hljs-keyword\">return<\/span> Mathf.PerlinNoise(x , y) * height;\n}\n\n...\n\nvertices&#91;index] = <span class=\"hljs-keyword\">new<\/span> Vector3(worldPosition.x, getElevation(normalizedPosition.x, normalizedPosition.y), worldPosition.y);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Si noti che, pur passando a <code>getElevation<\/code> le coordinate normalizzate, sarebbe stato corretto anche passare le coordinate effettive dei vertici (e, anzi, solitamente si fa cos\u00ec). Ho preferito fare in questo modo per mantenere la logica che garantisce l&#8217;indipendenza tra la deformazione del terreno e il valore della variabile <code>scale<\/code> visibile all&#8217;esterno della funzione.<\/p>\n\n\n\n<p>Poich\u00e9 le coordinate sono sempre normalizzate in un range 0-1, il Perlin noise \u00e8 calcolato su coordinate con la stessa magnitudine, indipendentemente dalle dimensioni della mappa. Questo garantisce generazioni identiche anche con dimensioni della mappa molto diverse. La variabile height, volendo, pu\u00f2 essere scalata dinamicamente in modo da mantenere anche l&#8217;altezza della deformazione costante su scale diverse.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-perlin-noise-e-ottave\">Perlin noise e ottave<\/h2>\n\n\n\n<p>Il terreno che abbiamo ottenuto nel paragrafo precedente \u00e8 abbastanza noioso e piuttosto <strong>artificiale<\/strong>. Non assomiglia molto a una catena montuosa e manca di dettagli.<\/p>\n\n\n\n<p>Per risolvere il problema dobbiamo trovare un modo per aggiungere imperfezioni ai valori ottenuti dal Perlin noise. Una tecnica usatissima per fare proprio questo \u00e8 la <strong>tecnica delle ottave<\/strong>.<\/p>\n\n\n\n<p>Quello che si fa \u00e8 usare come rumore non uno, ma <strong>pi\u00f9 Perlin noise sommati tra di loro<\/strong>.<\/p>\n\n\n\n<p>Il concetto riprende le ottave musicali. Questa tecnica prevede di partire con un Perlin noise semplice, con frequenza bassa e ampiezza alta.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Per frequenza si intende quanto velocemente variano i valori del Perlin noise<\/li>\n\n\n\n<li>Per ampiezza si intende quanto grandi sono questi valori<\/li>\n<\/ul>\n\n\n\n<p>A partire da una frequenza e un&#8217;ampiezza iniziale, si generano via via Perlin noise con <strong>frequenza doppia ma ampiezza dimezzata<\/strong>. Ciascun Perlin noise \u00e8 poi sommato al precedente, e il processo viene ripetuto un certo numero, finito, di volte. Ciascun passaggio aumenta il <strong>dettaglio del rumore di output<\/strong>, permettendo quindi al nostro paesaggio di assumere un aspetto ben pi\u00f9 naturale.<\/p>\n\n\n\n<p>Implementiamo allora una funzione che calcoli il Perlin noise con un certo numero di ottave:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>float octaveNoise(float x, float y, int octaveCount, float baseFrequency , float baseAmplitude, float lacunarityValue, float persistenceValue)\n<\/span><\/span><span class='shcb-loc'><span>{\n<\/span><\/span><span class='shcb-loc'><span>    float frequency = baseFrequency;\n<\/span><\/span><span class='shcb-loc'><span>    float amplitude = baseAmplitude;\n<\/span><\/span><span class='shcb-loc'><span>    float totalAmplitude = 0;\n<\/span><\/span><span class='shcb-loc'><span>    float value = 0;\n<\/span><\/span><span class='shcb-loc'><span>    for (int i = 0; i <span class=\"hljs-tag\">&lt; <span class=\"hljs-attr\">octaveCount<\/span>; <span class=\"hljs-attr\">i<\/span>++)<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">    {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">        <span class=\"hljs-attr\">value<\/span> += <span class=\"hljs-string\">Mathf.PerlinNoise(x<\/span> * <span class=\"hljs-attr\">frequency<\/span>, <span class=\"hljs-attr\">y<\/span> * <span class=\"hljs-attr\">frequency<\/span>) * <span class=\"hljs-attr\">amplitude<\/span>;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">        <span class=\"hljs-attr\">totalAmplitude<\/span> += <span class=\"hljs-string\">amplitude;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">        <span class=\"hljs-attr\">frequency<\/span> *= <span class=\"hljs-string\">lacunarityValue;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">        <span class=\"hljs-attr\">amplitude<\/span> *= <span class=\"hljs-string\">persistenceValue;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">    }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\"><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">    <span class=\"hljs-attr\">return<\/span> <span class=\"hljs-attr\">value<\/span> \/ <span class=\"hljs-attr\">totalAmplitude<\/span>;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-tag\">}<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Si noti che qui specifichiamo anche di quanto via via scalare frequenza e ampiezza, rispettivamente tramite <code>lacunarityValue<\/code> e <code>persistenceValue<\/code>. Il valore calcolato come somma delle ottave, prima di essere ritornato dalla funzione, viene normalizzato tramite divisione per la somma delle ampiezze di ogni ottava.<\/p>\n\n\n\n<p>Ora possiamo usare questa versione del Perlin noise nel nostro generatore procedurale:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">float getElevation(float x , float y)\n{\n    <span class=\"hljs-keyword\">return<\/span> octaveNoise(x, y, terrainOctaves, terrainBaseFrequency, terrainBaseAmplitude, terrainLacunarity, terrainPersistence) * height;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-un-po-di-colore\">Un po&#8217; di colore<\/h2>\n\n\n\n<p>Ora che abbiamo un terreno che ha un aspetto accettabile, possiamo divertirci a colorarlo come preferiamo. Per fare ci\u00f2 ho creato un piccolo <strong>shader <\/strong>tramite <strong>shader graph<\/strong> usato dal materiale associato al terreno.<\/p>\n\n\n\n<p>Il compito di questo shader \u00e8 colorare di verde le zone pi\u00f9 pianeggianti, di marrone le zone di montagna e le zone pendenti, e di bianco le zone pi\u00f9 alte, come se le cime delle montagne siano coperte di neve.<\/p>\n\n\n\n<p>Per colorare in maniera diversa zone pianeggianti e zone montuose, calcoliamo il <strong>prodotto scalare<\/strong> tra la <strong>normale del terreno<\/strong> e il vettore unitario che rappresenta <strong>l&#8217;asse verticale del mondo di gioco<\/strong>. <\/p>\n\n\n\n<p>Fare ci\u00f2 ci restituisce un valore che \u00e8 pari a 1 se i due vettori puntano entrambi nello stesso verso, e minore di uno se puntano in direzioni diverse. Man mano che i vettori diventano ortogonali, il prodotto scalare approccia zero.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"500\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-2.png\" alt=\"Pi\u00f9 la normale si discosta dal vettore verticale al mondo di gioco, pi\u00f9 il terreno si colora di marrone.\" class=\"wp-image-33825\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-2.png 500w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-2-300x300.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-2-150x150.png 150w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-2-100x100.png 100w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><figcaption class=\"wp-element-caption\">Schema riassuntivo del funzionamento dello shader per la colorazione del terreno. L&#8217;inclinazione del terreno, data dalla normale, \u00e8 usata per fare il sample del colore da utilizzare a partire da un gradiente realizzato appositamente.<\/figcaption><\/figure><\/div>\n\n\n<p>Questo fa s\u00ec che i punti del terreno pi\u00f9 in pendenza assumano un colore marrone, mentre i punti meno in pendenza si colorino di verde.<\/p>\n\n\n\n<p>Per fare in modo che le cime delle montagne siano innevate, possiamo semplicemente valutare la posizione di ciascun vertice in relazione al bounding box del terreno, e aggiungere al colore derivante dal procedimento spiegato sopra un colore bianco<strong> che \u00e8 tanto pi\u00f9 chiaro quanto pi\u00f9 in alto si trova il vertice rispetto al bounding box<\/strong>. Questo sistema \u00e8 ottimo quando siamo sicuri che il terreno assuma un certo valore massimo in prossimit\u00e0 della cima di una montagna, ma va adattato meglio nel caso in cui si prevedano chunk di terreno pianeggianti, eventualmente inserendo un threshold assoluto o in altro modo.<\/p>\n\n\n\n<p>Lo shader graph finale \u00e8 il seguente:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"685\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3-1024x685.png\" alt=\"La posizione y nello spazio oggetto, divisa per il bounds size, viene usata per prelevare il colore da un gradiente e applicarlo alla cima delle montagne \" class=\"wp-image-33826\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3-1024x685.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3-300x201.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3-768x514.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3-600x400.png 600w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-3.png 1375w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>E il risultato complessivo \u00e8 questo:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"605\" height=\"411\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\" alt=\"Terreno generato proceduralmente, con una piccola zona pianeggiante verde e aree montagnose che la circondano\" class=\"wp-image-33827\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png 605w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-300x204.png 300w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><figcaption class=\"wp-element-caption\">Una piccola pianura \u00e8 stata aggiunta per mostrare meglio le differenze tra montagne e sezioni pianeggianti. La pianura \u00e8 ottenuta sommando al perlin noise l&#8217;inverso di un perlin noise a 5 ottave elevato al quadrato.<\/figcaption><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-considerazioni-aggiuntive\">Considerazioni aggiuntive<\/h2>\n\n\n\n<p>Questo articolo funge da <strong>esempio base<\/strong> per quello che l&#8217;universo della generazione procedurale del terreno. Ci sarebbe moltissimo da aggiungere a un sistema del genere, ma si tratta pur sempre di un punto di partenza utile per comprendere i concetti fondamentali di queste metodologie.<\/p>\n\n\n\n<p>A questo punto sarebbe interessante riscrivere la generazione del terreno utilizzando un vertex shader, gestire la generazione di chunk e biomi, approfondire tecniche di ottimizzazione e di LOD e molto altro. Le possibilit\u00e0 sono infinite!<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nel contesto del game developement, la generazione procedurale del terreno \u00e8 una tecnica che utilizza algoritmi specifici per creare automaticamente ambienti di gioco (montagne, colline, isole&#8230;) in modo dinamico, ovvero senza che gli sviluppatori debbano realizzarli a mano. La generazione procedurale \u00e8 particolarmente comuni in giochi in cui si vuole fare in modo che il&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\">Read more<\/a><\/p>\n","protected":false},"author":267,"featured_media":33827,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[10305],"tags":[13479,13477],"collections":[],"class_list":{"0":"post-33833","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-sviluppo-videogiochi","8":"tag-game-developement","9":"tag-unity","10":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Le basi della generazione procedurale di terreno in Unity - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Le basi della generazione procedurale di terreno in Unity\" \/>\n<meta property=\"og:description\" content=\"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-13T09:55:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-08-13T09:55:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\" \/>\n\t<meta property=\"og:image:width\" content=\"605\" \/>\n\t<meta property=\"og:image:height\" content=\"411\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Gabriele Scaggiante\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Gabriele Scaggiante\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\"},\"author\":{\"name\":\"Gabriele Scaggiante\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/93da9439daf0318085b3436d179b447f\"},\"headline\":\"Le basi della generazione procedurale di terreno in Unity\",\"datePublished\":\"2025-08-13T09:55:47+00:00\",\"dateModified\":\"2025-08-13T09:55:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\"},\"wordCount\":1796,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\",\"keywords\":[\"Game developement\",\"Unity\"],\"articleSection\":[\"sviluppo videogiochi\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\",\"name\":\"Le basi della generazione procedurale di terreno in Unity - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\",\"datePublished\":\"2025-08-13T09:55:47+00:00\",\"dateModified\":\"2025-08-13T09:55:48+00:00\",\"description\":\"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png\",\"width\":605,\"height\":411,\"caption\":\"risultato della generazione procedurale\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"sviluppo videogiochi\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Le basi della generazione procedurale di terreno in Unity\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/93da9439daf0318085b3436d179b447f\",\"name\":\"Gabriele Scaggiante\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/07\/ProfileImageSquare-100x100.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/07\/ProfileImageSquare-100x100.png\",\"caption\":\"Gabriele Scaggiante\"},\"description\":\"Video game developer by profession and blogger, I create advergames to help brands and companies promote themselves through gaming.\",\"sameAs\":[\"https:\/\/gabrielescaggiante.com\/\",\"https:\/\/www.linkedin.com\/in\/gabriele-scaggiante-100b54254\/\"],\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/gabriele-scaggiante\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Le basi della generazione procedurale di terreno in Unity - Codemotion Magazine","description":"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/","og_locale":"en_US","og_type":"article","og_title":"Le basi della generazione procedurale di terreno in Unity","og_description":"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.","og_url":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2025-08-13T09:55:47+00:00","article_modified_time":"2025-08-13T09:55:48+00:00","og_image":[{"width":605,"height":411,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png","type":"image\/png"}],"author":"Gabriele Scaggiante","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Gabriele Scaggiante","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/"},"author":{"name":"Gabriele Scaggiante","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/93da9439daf0318085b3436d179b447f"},"headline":"Le basi della generazione procedurale di terreno in Unity","datePublished":"2025-08-13T09:55:47+00:00","dateModified":"2025-08-13T09:55:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/"},"wordCount":1796,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png","keywords":["Game developement","Unity"],"articleSection":["sviluppo videogiochi"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/","url":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/","name":"Le basi della generazione procedurale di terreno in Unity - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png","datePublished":"2025-08-13T09:55:47+00:00","dateModified":"2025-08-13T09:55:48+00:00","description":"La generazione procedurale del terreno \u00e8 una tecnica algoritmica pensata per creare ambienti di gioco in modo dinamico.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png","width":605,"height":411,"caption":"risultato della generazione procedurale"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/le-basi-della-generazione-procedurale-di-terreno-in-unity\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/"},{"@type":"ListItem","position":3,"name":"sviluppo videogiochi","item":"https:\/\/www.codemotion.com\/magazine\/it\/frontend-it\/sviluppo-videogiochi\/"},{"@type":"ListItem","position":4,"name":"Le basi della generazione procedurale di terreno in Unity"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/93da9439daf0318085b3436d179b447f","name":"Gabriele Scaggiante","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/07\/ProfileImageSquare-100x100.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/07\/ProfileImageSquare-100x100.png","caption":"Gabriele Scaggiante"},"description":"Video game developer by profession and blogger, I create advergames to help brands and companies promote themselves through gaming.","sameAs":["https:\/\/gabrielescaggiante.com\/","https:\/\/www.linkedin.com\/in\/gabriele-scaggiante-100b54254\/"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/gabriele-scaggiante\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-600x400.png","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-600x411.png","author_info":{"display_name":"Gabriele Scaggiante","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/gabriele-scaggiante\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-150x150.png",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-300x204.png",300,204,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-100x100.png",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-180x128.png",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4.png",605,411,false],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-400x225.png",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-600x400.png",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/08\/image-4-600x411.png",600,411,true]},"uagb_author_info":{"display_name":"Gabriele Scaggiante","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/gabriele-scaggiante\/"},"uagb_comment_info":0,"uagb_excerpt":"Nel contesto del game developement, la generazione procedurale del terreno \u00e8 una tecnica che utilizza algoritmi specifici per creare automaticamente ambienti di gioco (montagne, colline, isole&#8230;) in modo dinamico, ovvero senza che gli sviluppatori debbano realizzarli a mano. La generazione procedurale \u00e8 particolarmente comuni in giochi in cui si vuole fare in modo che il&#8230;&hellip;","lang":"it","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/33833","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/267"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=33833"}],"version-history":[{"count":1,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/33833\/revisions"}],"predecessor-version":[{"id":33834,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/33833\/revisions\/33834"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/33827"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=33833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=33833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=33833"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=33833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}