Overview
"I want to make an open-world game, but how do I create such a huge map?"
Unity Terrain is Unity's built-in landscape creation system that lets you efficiently create vast natural environments. You can sculpt terrain as if painting with a brush, apply textures, and place trees and grass to build realistic worlds.
Creating a Terrain
Simply select GameObject > 3D Object > Terrain from the menu to generate a flat 1000x1000 terrain.
Five Main Tools
| Tool | Description |
|---|---|
| Create Neighbor Terrains | Creates adjacent Terrain tiles |
| Paint Terrain | Sculpts terrain and paints textures |
| Paint Trees | Places trees |
| Paint Details | Places grass, flowers, rocks, and other details |
| Terrain Settings | General settings (size, resolution, performance) |
Paint Terrain: Sculpting and Painting
Sculpting Tools
| Tool | Description |
|---|---|
| Raise or Lower Terrain | Raises or lowers terrain height (hold Shift to lower) |
| Set Height | Sets a specific height (useful for creating flat plateaus) |
| Smooth Height | Smooths the terrain |
| Stamp Terrain | Stamps the brush shape onto terrain |
| Paint Holes | Creates holes in the terrain (for cave entrances, etc.) |
Creating Caves:
- Use Paint Holes to create a hole in the terrain
- Place a cave 3D mesh at the hole position
- Seamlessly connect the mesh edges with the Terrain boundary
- Add colliders as needed
Shortcuts
| Key | Function |
|---|---|
, . | Switch brushes |
[ ] | Change brush size |
- = | Change opacity |
F | Focus camera on cursor position |
Terrain Layers: Texture Painting
Creating Terrain Layers
- Select the Paint Terrain tool
- Select
Paint Texturefrom the dropdown - Click
Edit Terrain Layers > Create Layer - Configure textures (Diffuse, Normal Map, Mask Map, etc.)
Painting Textures
- Select a Terrain Layer
- Set brush size and opacity
- Drag across the terrain to paint
Painting at low opacity naturally blends with the layer beneath.
Terrain Layer Limits
| Render Pipeline | Max Layers | Notes |
|---|---|---|
| URP | 8 layers | Performance decreases as shader passes increase |
| Mobile (recommended) | 4 layers | To maintain performance |
| Built-in | No limit | But additional draw passes for every 4 layers |
Note: As the number of layers increases, draw passes increase and performance degrades significantly. For mobile, keep it within 4 layers.
Trees: Placing Trees
Adding Trees
- Select the Paint Trees tool
- Click
Edit Trees > Add Tree - Select a tree Prefab
- Drag across the terrain to place trees (hold Shift to remove)
Mass Place Trees
Use Mass Place Trees to randomly place trees across the entire terrain at once.
Tree Settings
| Setting | Description |
|---|---|
| Bend Factor | Strength of wind sway |
| Billboard Start | Distance at which trees switch to billboard rendering |
SpeedTree vs Regular Mesh: SpeedTree assets have built-in LOD Groups and automatically transition between LOD levels, while regular meshes only switch to billboards. For high-quality trees, SpeedTree-compatible assets are recommended.
Details: Placing Grass and Details
Detail Types
| Type | Description |
|---|---|
| Grass | Rendered as billboards (quads). Lightweight |
| Detail Mesh | Rendered as 3D meshes. More realistic appearance |
Adding Details
- Select the Paint Details tool
- Click
Edit Details > Add Grass TextureorAdd Detail Mesh - Drag across the terrain to place
Terrain Settings: Configuration and Performance Optimization
Basic Settings
| Setting | Description |
|---|---|
| Terrain Width/Length/Height | Terrain size |
| Heightmap Resolution | Heightmap resolution (2^n + 1) |
| Detail Resolution | Detail resolution |
Heightmap Resolution Guidelines
| Project Scale | Resolution | Notes |
|---|---|---|
| Prototype / Small | 257x257 | Low memory usage |
| Typical Game | 513x513 | Good balance |
| Large Open World | 1025x1025 | High detail but high memory usage |
| Very Large | 2049x2049+ | Recommended to split into multiple tiles |
Detail Resolution Guidelines
| Project | Resolution | Detail Resolution Per Patch |
|---|---|---|
| Mobile | 512-1024 | 8 |
| PC/Console | 1024-2048 | 16 |
| High Quality | 2048-4096 | 32 |
Performance Settings
| Setting | Description |
|---|---|
| Pixel Error | LOD accuracy (5-50 is typical) |
| Base Map Distance | Distance at which the base map takes over |
| Detail Distance | Distance at which details are visible |
| Tree Distance | Distance at which trees are visible |
| Draw Instanced | Speeds up rendering using GPU Instancing |
Draw Instanced: Enabling this option speeds up Terrain rendering using GPU Instancing. This is especially effective when using multiple Terrain tiles.
Wind Settings
Under Terrain Settings > Wind Settings for Grass, you can configure grass sway.
| Setting | Description |
|---|---|
| Speed | Wind speed |
| Size | Wind wave size |
| Bending | How much the grass bends |
Grass Tint: The "Grass Tint" setting in the same section adjusts the grass color tone and is separate from wind effects.
Wind Settings Scope:
- Details (Grass Texture, Detail Mesh) - Affected
- Trees (placed via Paint Trees) - Not affected (Trees use Bend Factor individually. SpeedTree assets use SpeedTree's own Wind settings)
Multiple Terrain Tiles
For large maps, splitting into multiple Terrain tiles can improve performance.
Creating Tiles
- Select a Terrain
- Click the Create Neighbor Terrains tool
- Choose which direction to create a tile
Tiles are automatically connected seamlessly.
Batch Management with TerrainGroup
For large maps, use Terrain.SetNeighbors() to set up connections between tiles, and the TerrainGroup component to manage multiple Terrains collectively.
Terrain Tools: The Terrain Tools package (pre-installed in some Unity 2022+ versions) makes batch editing of multiple tiles even more convenient.
Heightmap Import/Export
Under Terrain Settings > Import Raw / Export Raw, you can import and export 16-bit RAW format files. Use this for integration with external tools like World Machine or Gaia, or for generating terrain from grayscale images created in Photoshop.
Scripting Terrain Modifications
You can modify terrain from scripts using TerrainData.
using UnityEngine;
public class TerrainModifier : MonoBehaviour
{
Terrain terrain;
TerrainData terrainData;
void Start()
{
terrain = GetComponent<Terrain>();
terrainData = terrain.terrainData;
}
// Get/set height (x, y are pixel coordinates)
// Important: heights array index is [y, x] (row, column) order
// terrainData.GetHeights(xBase, yBase, width, height) takes (x, y) order,
// but the returned array is accessed via heights[y, x]
public void ModifyHeight(int x, int y, float height)
{
float[,] heights = terrainData.GetHeights(x, y, 1, 1);
heights[0, 0] = height; // Range: 0 to 1
terrainData.SetHeights(x, y, heights);
}
// Convert world coordinates to heightmap pixel coordinates (with bounds checking)
// For a heightmapResolution of 513, valid pixel coordinates are 0-512
public Vector2Int WorldToHeightmapCoord(Vector3 worldPos)
{
Vector3 terrainPos = worldPos - terrain.transform.position;
int maxIndex = terrainData.heightmapResolution - 1;
int x = Mathf.Clamp(
Mathf.RoundToInt(terrainPos.x / terrainData.size.x * maxIndex),
0, maxIndex);
int y = Mathf.Clamp(
Mathf.RoundToInt(terrainPos.z / terrainData.size.z * maxIndex),
0, maxIndex);
return new Vector2Int(x, y);
}
// Set texture (Alphamap)
public void PaintTexture(int x, int y, int layerIndex)
{
float[,,] alphas = terrainData.GetAlphamaps(x, y, 1, 1);
// Reset all layers
for (int i = 0; i < alphas.GetLength(2); i++)
alphas[0, 0, i] = 0;
alphas[0, 0, layerIndex] = 1;
terrainData.SetAlphamaps(x, y, alphas);
}
}
Use cases: Procedural terrain generation, runtime terrain modification (digging, leveling, etc.).
Coordinate system note:
heightmapResolutionandalphamapResolutionmay return different values. Be careful not to mix up Heightmap and Alphamap coordinates.
Heightmap vs Alphamap Resolution:
| Property | Value Pattern | Example |
|---|---|---|
| heightmapResolution | 2^n + 1 | 513, 1025 |
| alphamapResolution | 2^n | 512, 1024 |
Procedural Terrain Generation with Perlin Noise
public void GenerateProceduralTerrain(float scale, float heightMultiplier)
{
int res = terrainData.heightmapResolution;
float[,] heights = new float[res, res];
// Add offsets to generate variation,
// since Mathf.PerlinNoise always returns the same result for the same input
float offsetX = Random.Range(0f, 10000f);
float offsetY = Random.Range(0f, 10000f);
for (int y = 0; y < res; y++)
{
for (int x = 0; x < res; x++)
{
heights[y, x] = Mathf.PerlinNoise(
(x + offsetX) / (float)res * scale,
(y + offsetY) / (float)res * scale
) * heightMultiplier;
}
}
terrainData.SetHeights(0, 0, heights);
}
Terrain Tools Package
Installing the Terrain Tools package unlocks additional sculpting tools and advanced features like erosion simulation.
Installation
- Select
Window > Package Manager - Click the
+button and selectAdd package by name... - Enter
com.unity.terrain-toolsand install
Additional Tools
| Tool | Description |
|---|---|
| Bridge | Connects two points with a bridge |
| Clone | Copies and pastes parts of the terrain |
| Erosion | Erosion simulation (weathering, water flow, etc.) |
| Terrace | Creates step-like terraced terrain |
| Noise | Noise-based terrain generation |
Summary
Unity Terrain is a powerful system for efficiently creating large-scale natural environments.
- Paint Terrain - Sculpt terrain and paint textures with brushes
- Paint Trees / Paint Details - Quickly place trees and grass
- LOD and Culling - Robust performance optimization features
- Multiple Tiles - Scales to massive open worlds
Use Terrain to build your own vast worlds.