[Unity] Coroutine(코루틴) 파헤치기
·
Unity,C#/Unity 정보
■ 동기(Synchronous)와 비동기(Asynchronous)동기와 비동기는 작업을 처리하는 방식의 차이를 나타내는 개념이다. 프로그래밍에서는 아래와 같은 의미로 사용된다.동기(Synchronous) : 작업이 순차적으로, 동일한 흐름 내에서 처리된다. 앞선 작업이 끝나야 다음이 실행된다.(일반적인 코드 실행 흐름.)OrderFood();Pay(); // => OrderFood()가 끝나야 실행.PrintReceipt(); // => Pay()가 끝나야 실행.비동기(Asynchronous) : 작업이 병렬적으로, 또는 다른 흐름에서 실행될 수 있다. 하나의 작업이 완료되기를 기다리지 않고, 그 사이 다른 작업이 함께 진행될 수 있다. public class Asynchronous ..
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 5. 벽 생성
·
Unity,C#/절차적생성(PCG)
■ 벽 생성 이제 BSP 알고리즘으로 생성한 던전에 벽을 배치하여 마무리한다.벽은 Mesh를 사용해서 통으로 생성하는 것이 아니라, 벽 오브젝트를 1 유닛 단위로 배치하여 맵 전체를 감싸는 방식으로 구현한다. ■ 상세 구현벽 생성 로직 자체는 비교적 단순하다.각 방의 좌하단→우하단(수평), 좌하단 → 좌상단(수직) 방향으로 1씩 좌표를 증가시키며, 벽을 배치할 좌표를 저장한다.동일하게 반대 방향(좌상단→ 우상단(수평), 우하단 → 우상단(수직)) 방향도 기록한다.좌표 기록은 바닥 Mesh를 생성할 때 같이 진행한다.단, 복도와 겹치는 구간에는 벽을 생성하면 안 된다.따라서 벽을 배치할 좌표를 저장할 때, 이미 기록된 좌표가 넘어온다면 복도와 겹치는 공간이므로 저장된 좌표를 삭제한다.public class..
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 4. 복도 생성
·
Unity,C#/절차적생성(PCG)
■ 복도 생성 BSP로 완성된 이진트리를 역방향으로 순회하며, 자식 노드에 생성된 방 사이를 복도로 연결한다. 복도 생성은 다음과 같은 흐름으로 진행된다. 복도 생성 절차트리의 가장 깊은 곳부터 시작하여, 자식 노드를 가진 부모 노드를 찾는다.두 자식 노드의 상대적인 위치(상,하,좌,우)를 파악한다.두 방이 연결 가능한 위치에 있는지 확인한다.연결이 가능하다면 복도를 생성한다. 연결이 불가능하다면, 다른 노드를 대상으로 연결 가능 여부를 다시 체크한다. ■ 상세 구현 내용1. 연결 대상 찾기using System.Collections.Generic;using System.Linq;public class CorridorGenerator{ private List _roomNodes; private..
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 3. BSP 알고리즘 개선
·
Unity,C#/절차적생성(PCG)
2025/05/15- 조건부 분할 위치를 계산하는 부분에서 offset * 2를 기준으로 방 최소 사이즈를 만족하는지 확인하는 코드 수정.- 코드 변경에 따른 최종 결과 갱신.■ BSP 알고리즘 개선 현재 구현된 BSP 알고리즘은 분할 조건이 단순하기 때문에, 분할 방향이 한쪽(가로 또는 세로)으로만 생성되어 지나치게 긴 복도가 생성되는 경우가 존재한다.따라서 추가 조건을 생성하여 균등하게 공간이 분할될 수 있도록 수정한다. 1. 분할 방향 조건 추가var widthStatus = node.Width >= _data.RoomMinWidth * 2;var heightStatus = node.Height >= _data.RoomMinHeight * 2;var splitDir = (widthStatus, he..
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 2. 방 생성
·
Unity,C#/절차적생성(PCG)
■ 방 생성 BSP 알고리즘을 통해 공갈이 분할되면, 자식이 없는 단말(리프) 노드에 실제 방을 생성해야 한다. 단말 노드들은 더 이상 분할되지 않는 영역이기 때문이다.private List GetAllLeafNode(){ var leafNodes = new List(); var queue = new Queue(new[] { _roomNodeList[0] }); while (queue.Count > 0) { var node = queue.Dequeue(); if (node.ChildNode.Count 너비 우선 탐색(BFS) 방식으로 트리를 순회하며, 자식 노드가 없는 경우(단말 노드)만 리스트에 추가한다. ■ 방 생성 구현public class RoomGenerator{ private..
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 1. Binary Space Partitioning
·
Unity,C#/절차적생성(PCG)
2025-05-15 (수정사항)- NodePosition을 초기화 할 때 (좌상단, 우하단)기준에서 (좌하단, 우상단)기준으로 초기화하도록 수정. ■ 이진 공간 분할법 - Binary Space Partitioning(BSP) BSP 알고리즘은 공간을 재귀적으로 둘로 분할해 가며 이진트리를 구성하는 알고리즘이다. 최종적으로 자식이 없는 리프 노드에 각 분할된 공간이 저장된다.이를 활용하여 던전등의 지형을 절차적으로 생성할 수 있다. BSP 알고리즘 동작 순서현재 공간의 분할 방향(수직, 수평)을 결정한다.선택된 방향으로 공간을 2개로 분할, 이 공간을 큐에 추가한다.분할된 공간에 대해 1~2번의 과정을 더 이상 분할이 불가능할때까지 반복한다. ■ BSP 구현1. BSP 트리 노드 구성using Syste..
[C#, Unity, 절차적 생성] 절차적 지형 생성 - 3.터레인 생성
·
Unity,C#/절차적생성(PCG)
■ 터레인 생성 앞서 생성했던 PerlinNoise 맵을 HeightMap으로 사용하여 Terrain을 만들어보자. Unity에서 Terrain을 생성하는 과정은 매우 간단하다. 1. Terrain 생성 코드public void CreateTerrain(){ var terrainData = terrain.terrainData; terrainData.heightmapResolution = Mathf.Max(noiseData.Width, noiseData.Height); terrainData.size = new Vector3(noiseData.Width, maxHeight, noiseData.Height); terrainData.SetHeights(0, 0, _fractalMap); Set..
[C#, Unity, 절차적 생성] 절차적 지형 생성 - 2.프랙탈 합
·
Unity,C#/절차적생성(PCG)
■ 프랙탈 합(Fractal Noise)하나의 PerlinNoise는 큰 흐름만 존재하고 세부 디테일이 부족하기 때문에, 복잡한 자연 지형을 표현하기엔 한계가 있다.복잡한 자연 지형을 표현하기 위해 동일한 PerlinNoise를 여러 옥타브(Octave)에 걸쳐 주파수(Frequency - 빈도)는 높이고, 진폭(Amplitude-세기)은 줄이며 반복적으로 합산한 복합 노이즈인 프렉탈 합(Fractal Noise)를 사용한다.이러한 방식은 fBm(Fractal Brownian Motion)이라고도 불리며, 다양한 랜덤 패턴의 기반이 된다.Fractal Noise는 자연 지형, 구름, 바위 텍스처 등의 절차적 생성에 사용된다. 보통 다음과 같은 파라미터로 주파수와 진폭을 제어한다.Lacunarity : 주..
[C#, Unity, 절차적 생성] 절차적 지형 생성 - 1.PerlinNoise
·
Unity,C#/절차적생성(PCG)
■ PerlinNoise PerlinNoise는 1983년 Ken Perlin이 개발한 그래디언트 기반의 노이즈(Gradient Noise)함수로, 지형의 절차적 생성, 텍스처 생성, 구름이나 연기 같은 자연 현상 표현 등 다양한 절차적 콘텐츠 생성에 활용된다. 1. Noise함수 Noise함수는 입력값에 따라 “의사 난수(Pseudo-random)”값을 반환하는 함수다. 일반적인 난수와 달리, 입력값이 비슷할수록 결과값도 유사해지는 부드러운 변화를 가진다.// 호출할 때마다 완전히 다른 값.Random.Range(0f, 1f);// 항상 같은 입력에 같은 결과.Mathf.PerlinNoise(x, y);// 입력이 조금 달라지면, 출력도 조금만 변화 -> 부드러운 노이즈Mathf.PerlinNoise..