Essay - Published: 2021.01.30 | csharp | procedural-generation | unity |
DISCLOSURE: If you buy through affiliate links, I may earn a small commission. (disclosures)

I've been learning about Unity on my journey to better understand the 3D programming space. In this post I'll be sharing a procedurally-generated work I created in Unity as well as the C# code I built it with.
Before we begin, let's define procedural generation. From Wikipedia:
procedural generation is a method of creating data algorithmically as opposed to manually, typically through a combination of human-generated assets and algorithms coupled with computer-generated randomness and processing power.
Procedural generation leverages the flexibility of data and the power of processing to create near limitless combinations of outputs.
Unity's dominating script language is C#. I also happen to love C# so that's what I built this example in.
In the example, we leverage randomness to determine the color and height of cubes we've arranged in a grid (see cover photo). The randomness provides the input data and we use the computational power of code to generate hundreds and thousands of cubes to use it on.
Code:
using System;
using UnityEngine;
public class SeaCubeController : MonoBehaviour {
public GameObject GeneratedObjectHolder;
public Material PrimaryMaterial;
public Material SecondaryMaterial;
public int StartXLocation = 0;
public int StartZLocation = 0;
public int CountX = 20;
public int CountZ = 20;
public float CubeSize = 2.0f;
public float CubeSpacingMultiplier = 0.01f;
public void Start() {
var cubeSpacing = CubeSize + CubeSize * CubeSpacingMultiplier;
var random = new System.Random();
for(var x = 0; x < CountX; x++) {
for(var z = 0; z < CountZ; z++) {
var position = new Vector3(
-1 * x * cubeSpacing,
((float)random.NextDouble()) * CubeSize,
z * cubeSpacing
);
var cube = GameObject.CreatePrimitive(
PrimitiveType.Cube
);
cube.transform.position = position;
cube.transform.localScale = new Vector3(
CubeSize,
CubeSize,
CubeSize
);
cube.transform.parent = GeneratedObjectHolder.transform;
var cubeRenderer = cube.GetComponent<Renderer>();
if(random.NextDouble() < 0.1) {
cubeRenderer.material = SecondaryMaterial;
} else {
cubeRenderer.material = PrimaryMaterial;
}
}
}
}
}
The best way to support my work is to like / comment / share for the algorithm and subscribe for future updates.