Unity: Procedural Generation with Unity3D and C#
Date: 2021-01-30 | unity | csharp | procedural-generation |
Overview
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.
Procedural Generation
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.
Procedural Generation with Unity
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;
}
}
}
}
}
- First we initialize several variables which we'll use as rules in our generation
- Next we iterate over our grid of cubes (in Unity y is up, so we use z and x to iterate over the grid) and determine where that object is located in world space
- We then create a cube in that location and randomly assign a color (via a material) to that cube
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.