반응형
🤔 랜덤 워커 알고리즘이란??
워커(걷는 친구)가 맵을 랜덤으로 상하좌우로 돌아다니면서 맵을 채우는 알고리즘
이렇게 워커가 맵을 자유롭게 돌아다니면서 맵을 넓히는 알고리즘 이다. 이때 이전 위치에 visit처리를 해줘야지 코드가 무한 반복 되는 것을 막을 수 있다. ( ex. 위->아래->위->아래->위->아래->위->아래 ... )
🎈결과
😎 느낀점
랜덤하게 움직여서 다양한 맵을 생성할 수 있다는 장점이 있지만, 맵의 크기가 너무 불규칙하다는 큰 단점 때문에 사용하지는 않을 것 같다.
💻 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RandomWalker : MonoBehaviour
{
// 맵 크기 및 노드 간 거리 설정
public int mapSize = 16;
public int nodeDistance = 10;
public int walkerCnt = 1;
// 노드와 랜덤 워커의 프리팹
public GameObject Prefab_node;
public GameObject Prefab_walker;
// 현재 움직이고 있는 워커 오브젝트
GameObject currentWorker;
// 맵 데이터와 방문 여부를 저장하는 2차원 배열
int[][] maps;
bool[][] visit;
private void Start()
{
// 맵 데이터 초기화
Setup();
// 코루틴을 이용해 랜덤 워커 생성 시작
StartCoroutine(StartGenerate(walkerCnt));
}
// 맵 데이터 및 방문 여부 초기화
void Setup()
{
maps = new int[mapSize][];
visit = new bool[mapSize][];
for (int i = 0; i < mapSize; i++)
{
maps[i] = new int[mapSize];
visit[i] = new bool[mapSize];
}
}
// 지정된 개수만큼 랜덤 워커를 생성하는 코루틴
IEnumerator StartGenerate(int WalkerCnt)
{
// 워커가 맵 중앙에서 시작하도록 설정
int startX = mapSize / 2;
int startY = mapSize / 2;
for (int i = 0; i < WalkerCnt; i++)
{
// 워커(이동 객체) 생성 및 현재 워커로 저장
GameObject worker = Instantiate(Prefab_walker);
currentWorker = worker;
// 랜덤 워커 프로세스를 시작하고, 완료될 때까지 대기
yield return StartCoroutine(RandomWalkerProcess(startY, startX));
// 방문 데이터 초기화 (새로운 워커가 시작할 수 있도록)
ResetVisit();
}
}
// 방문 배열을 리셋하는 함수
void ResetVisit()
{
for (int i = 0; i < mapSize; ++i)
{
for (int j = 0; j < mapSize; ++j)
{
visit[i][j] = false;
}
}
}
// 랜덤 워커의 이동을 처리하는 코루틴
IEnumerator RandomWalkerProcess(int y, int x)
{
// 현재 위치 방문 처리
visit[y][x] = true;
// 이동 간격(0.25초) 대기
yield return new WaitForSeconds(0.25f);
// 현재 워커의 위치 갱신
currentWorker.transform.position = new Vector3(x * nodeDistance, 1, y * nodeDistance);
// 아직 노드가 생성되지 않은 경우, 새로운 노드 생성
if (maps[y][x] != 1)
{
GameObject newObj = Instantiate(Prefab_node);
newObj.transform.position = new Vector3(x * nodeDistance, 0, y * nodeDistance);
newObj.transform.SetParent(this.transform);
newObj.name = $"[{y},{x}] node";
maps[y][x] = 1; // 해당 위치를 노드로 표시
}
// 랜덤 방향 선택 (0: 왼쪽, 1: 오른쪽, 2: 위쪽, 3: 아래쪽)
int randomNum = Random.Range(0, 4);
if (randomNum == 0 && x - 1 >= 0 && !visit[y][x - 1])
{
yield return StartCoroutine(RandomWalkerProcess(y, x - 1)); // 왼쪽 이동
}
if (randomNum == 1 && x + 1 < mapSize && !visit[y][x + 1])
{
yield return StartCoroutine(RandomWalkerProcess(y, x + 1)); // 오른쪽 이동
}
if (randomNum == 3 && y - 1 >= 0 && !visit[y - 1][x])
{
yield return StartCoroutine(RandomWalkerProcess(y - 1, x)); // 위쪽 이동
}
if (randomNum == 2 && y + 1 < mapSize && !visit[y + 1][x])
{
yield return StartCoroutine(RandomWalkerProcess(y + 1, x)); // 아래쪽 이동
}
}
}
반응형
'🎮 게임 제작' 카테고리의 다른 글
[Unity] Cake 탑을 쌓는 디스코드 경쟁 게임 "I LOVE CAKE" 개발후기 (0) | 2025.03.02 |
---|