PerlinNoise는 Ken Perlin이 1980년대 영화 “Tron”을 제작하는 동안 컴퓨터 효과를 위한 그라데이션 텍스처를 만들기 위해 만들었습니다.
개발한 노이즈 기능입니다.
노이즈 함수는 Minecraft 및 Terrari와 같은 많은 분야에서 사용됩니다.
설정된 규칙에 따라 게임 내 콘텐츠 자동 생성 “프로그램 콘텐츠 생성” 사용하는 게임에 적용할 수 있습니다.
이 노이즈 함수는 Unity에서 Mathf.PerlinNoise() 메서드로 제공됩니다.
그런 다음 텍스처에 노이즈를 칠하고 눈으로 노이즈를 검사해 보겠습니다.
노이즈 텍스처
using UnityEngine;
public class PerlinNoise : MonoBehaviour
{
public int width = 256;
public int height = 256;
public float scale = 20f;
public float offsetX;
public float offsetY;
private void Start()
{
offsetX = Random.Range(0f, 99999f);
offsetY = Random.Range(0f, 99999f);
}
private void Update()
{
Renderer renderer = GetComponent<Renderer>();
renderer.material.mainTexture = GenerateTexture();
}
Texture2D GenerateTexture()
{
Texture2D texture = new Texture2D(width, height);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Color color = CalculateColor(x, y);
texture.SetPixel(x, y, color);
}
}
texture.Apply();
return texture;
}
Color CalculateColor(int x, int y)
{
float xCoord = (float)x / width * scale + offsetX;
float yCoord = (float)y / height * scale + offsetY;
float sample = Mathf.PerlinNoise(xCoord, yCoord);
return new Color(sample, sample, sample);
}
}
오브젝트를 생성하여 텍스처를 적용하면 위와 같이 노이즈를 확인할 수 있습니다.
이 노이즈 기능은 게임의 다양한 부분에 적용될 수 있습니다.
파도
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wave : MonoBehaviour
{
float scale;
float heightScale;
int planeSize;
public GameObject cube;
void Start()
{
scale = 0.2f;
heightScale = 2f;
planeSize = 25;
for (int x = 0; x < planeSize; x++)
{
for (int z = 0; z < planeSize; z++)
{
var c = Instantiate(cube, new Vector3(x, 0, z), Quaternion.identity);
c.transform.parent = transform;
}
}
}
void Update()
{
foreach (Transform child in transform)
{
child.transform.position = new Vector3(child.transform.position.x,
heightScale * Mathf.PerlinNoise(Time.time + (child.transform.position.x * scale),
Time.time + (child.transform.position.z * scale)),
child.transform.position.z);
}
}
}
높이 지도
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PerlinColor : MonoBehaviour
{
public int size;
public GameObject cube;
public float scale;
public float m;
bool move;
float height;
void Start()
{
move = true;
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
var c = Instantiate(cube, new Vector3(x, 0, z), Quaternion.identity);
c.transform.parent = transform;
}
}
}
void Update()
{
foreach (Transform child in transform)
{
height = Mathf.PerlinNoise(child.transform.position.x / scale, child.transform.position.z / scale);
child.GetComponent<MeshRenderer>().material.color = new Color(height, height, height, height);
}
if (move)
{
foreach (Transform child in transform)
{
height = Mathf.PerlinNoise(child.transform.position.x / scale, child.transform.position.z / scale);
child.transform.position = new Vector3(child.transform.position.x, Mathf.RoundToInt(height * m), child.transform.position.z);
// Mathf.RoundToInt() : 매개변수로 받은 두 정수중 가까운 정수를 반환합니다.
}
}
}
}
지역
using UnityEngine;
public class TerrainGenerator : MonoBehaviour
{
public int depth = 20;
public int width = 256;
public int height = 256;
public float scale = 20f;
public float offsetX = 100f;
public float offsetY = 100f;
private void Start()
{
offsetX = Random.Range(0f, 99999f);
offsetY = Random.Range(0f, 99999f);
}
private void Update()
{
Terrain terrain = GetComponent<Terrain>();
terrain.terrainData = GenerateTerrain(terrain.terrainData);
//offsetX += Time.deltaTime * 5f;
}
TerrainData GenerateTerrain(TerrainData terrainData)
{
terrainData.heightmapResolution = width + 1;
terrainData.size = new Vector3(width, depth, height);
terrainData.SetHeights(0, 0, GenerateHeights());
return terrainData;
}
float(,) GenerateHeights()
{
float(,) heights = new float(width, height);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
heights(x, y) = CalculateHeight(x, y);
}
}
return heights;
}
float CalculateHeight(int x, int y)
{
float xCoord = (float)x / width * scale + offsetX;
float yCoord = (float)y / height * scale + offsetY;
return Mathf.PerlinNoise(xCoord, yCoord);
}
}