로크라이크 게임에서 모듈화 코드의 중요성
로크라이크 게임의 핵심은 무작위성, 리플레이성, 예측 불가능한 이벤트에 있습니다. 이 요소들은 플레이어가 매번 새로운 경험을 하게 만들어 주지만, 개발자와 기획자 입장에서는 구현 과정이 쉽지 않은 작업입니다. 특히 유니티에서 로크라이크 게임을 개발할 때 자주 반복되는 기능들을 모듈화하여 재사용 가능한 코드를 제공하는 것이 효율적입니다. 이 글에서는 로크라이크 개발에서 즉시 활용할 수 있는 실용적인 코드 모음과 기능들을 소개해드리겠습니다.
목차
무작위 맵 생성기: 던전 구조를 만드는 기본 코드
로크라이크 게임에서 무작위로 생성되는 맵은 게임의 다양한 경험을 만들어 주는 중요한 요소입니다. 던전 스타일의 맵을 생성하는 데는 다양한 방법이 있지만, 그 중 가장 흔하게 사용하는 알고리즘 중 하나는 “방과 통로 연결” 방식입니다.
예시 코드: 방과 통로를 무작위로 배치하는 맵 생성기
아래 코드는 일정한 범위 내에 무작위로 방을 생성하고, 각 방을 통로로 연결해주는 방식으로 맵을 생성합니다. 이 코드는 던전의 구조를 만드는 데 효과적이며, 사용자가 쉽게 커스터마이징할 수 있도록 모듈화되어 있습니다.
using UnityEngine;
using System.Collections.Generic;
public class DungeonGenerator : MonoBehaviour {
public int dungeonWidth = 50;
public int dungeonHeight = 50;
public int roomCount = 10;
public int roomSizeMin = 3;
public int roomSizeMax = 8;
private int[,] map;
private List<Rect> rooms;
void Start() {
GenerateDungeon();
}
void GenerateDungeon() {
map = new int[dungeonWidth, dungeonHeight];
rooms = new List<Rect>();
for (int i = 0; i < roomCount; i++) {
int roomWidth = Random.Range(roomSizeMin, roomSizeMax);
int roomHeight = Random.Range(roomSizeMin, roomSizeMax);
int roomX = Random.Range(0, dungeonWidth - roomWidth);
int roomY = Random.Range(0, dungeonHeight - roomHeight);
Rect newRoom = new Rect(roomX, roomY, roomWidth, roomHeight);
bool roomOverlaps = false;
foreach (Rect room in rooms) {
if (newRoom.Overlaps(room)) {
roomOverlaps = true;
break;
}
}
if (!roomOverlaps) {
rooms.Add(newRoom);
CreateRoom(newRoom);
}
}
for (int i = 0; i < rooms.Count - 1; i++) {
Vector2Int roomCenterA = GetRoomCenter(rooms[i]);
Vector2Int roomCenterB = GetRoomCenter(rooms[i + 1]);
CreateCorridor(roomCenterA, roomCenterB);
}
}
void CreateRoom(Rect room) {
for (int x = (int)room.x; x < room.xMax; x++) {
for (int y = (int)room.y; y < room.yMax; y++) {
map[x, y] = 1;
}
}
}
void CreateCorridor(Vector2Int from, Vector2Int to) {
Vector2Int current = from;
while (current != to) {
map[current.x, current.y] = 1;
if (current.x < to.x) current.x++;
else if (current.x > to.x) current.x--;
if (current.y < to.y) current.y++;
else if (current.y > to.y) current.y--;
}
}
Vector2Int GetRoomCenter(Rect room) {
int centerX = (int)(room.x + room.width / 2);
int centerY = (int)(room.y + room.height / 2);
return new Vector2Int(centerX, centerY);
}
}
이 코드를 사용하면 맵 내에 랜덤한 방과 그 사이를 연결하는 통로가 생성됩니다. 각 방의 크기와 위치는 무작위로 설정되며, 방이 겹치지 않도록 중복 체크도 포함되어 있습니다. 이 맵 생성기를 통해 매번 새로운 던전을 경험하게 할 수 있습니다.
적 스폰 시스템: 특정 위치에서 무작위로 적 생성
로크라이크에서는 맵을 탐험할 때 언제 어디서 적이 나타날지 모르는 긴장감이 필요합니다. 적 스폰 시스템은 플레이어의 위치나 스테이지의 난이도에 따라 적을 배치하는 데 효과적입니다.
예시 코드: 플레이어 위치에 따른 적 스폰 코드
아래 코드는 플레이어 주변의 특정 위치에 무작위로 적을 스폰하는 방식입니다. 적의 종류와 수는 난이도에 따라 조절할 수 있습니다.
using UnityEngine;
public class EnemySpawner : MonoBehaviour {
public GameObject[] enemyPrefabs;
public int enemyCount = 5;
public float spawnRadius = 10f;
private Transform player;
void Start() {
player = GameObject.FindWithTag("Player").transform;
SpawnEnemies();
}
void SpawnEnemies() {
for (int i = 0; i < enemyCount; i++) {
Vector3 spawnPosition = player.position + Random.insideUnitSphere * spawnRadius;
spawnPosition.y = 0;
int randomEnemyIndex = Random.Range(0, enemyPrefabs.Length);
Instantiate(enemyPrefabs[randomEnemyIndex], spawnPosition, Quaternion.identity);
}
}
}
위 코드는 플레이어를 기준으로 무작위 위치에 적을 배치해줍니다. spawnRadius
변수를 통해 스폰 범위를 설정할 수 있으며, enemyPrefabs
배열을 통해 여러 종류의 적을 무작위로 생성할 수 있습니다.
아이템 드롭 시스템: 희소성에 따른 아이템 드롭 확률 구현
아이템 드롭 시스템은 적을 처치하거나 상자를 열 때 희귀 아이템을 얻을 확률을 설정하는 데 사용됩니다. 특정 아이템의 드롭 확률을 조정하여 플레이어에게 보상감을 줄 수 있습니다.
예시 코드: 가중치 기반의 아이템 드롭 시스템
아이템의 희소성을 조절하기 위해 가중치를 사용하여 드롭 확률을 설정하는 방식입니다.
[System.Serializable]
public class DropItem {
public GameObject itemPrefab;
public int dropWeight;
}
public class ItemDropManager : MonoBehaviour {
public List<DropItem> dropItems;
public GameObject GetRandomDrop() {
int totalWeight = 0;
foreach (DropItem item in dropItems) {
totalWeight += item.dropWeight;
}
int randomValue = Random.Range(0, totalWeight);
foreach (DropItem item in dropItems) {
if (randomValue < item.dropWeight) {
return item.itemPrefab;
}
randomValue -= item.dropWeight;
}
return null;
}
}
위 코드로 각 아이템의 가중치를 설정하여 희소성을 조절할 수 있습니다. dropWeight
값이 높은 아이템일수록 드롭 확률이 높아지므로, 이를 통해 플레이어가 희귀 아이템을 더 쉽게 얻거나 어렵게 얻도록 조정할 수 있습니다.
이벤트 발생 확률 시스템: 무작위 이벤트로 게임의 긴장감 조성
로크라이크에서 무작위 이벤트는 플레이어에게 예측할 수 없는 상황을 제공하여 몰입감을 높입니다. 예를 들어, 함정이 발동되거나 강력한 적이 나타나는 등의 상황을 연출할 수 있습니다.
예시 코드: 일정 확률로 무작위 이벤트 발생시키기
using UnityEngine;
public class RandomEventManager : MonoBehaviour {
public GameObject[] events; // 발생 가능한 이벤트 오브젝트 배열
public float triggerChance = 0.1f; // 10% 확률
void Update() {
if (Random.value < triggerChance * Time.deltaTime) {
TriggerRandomEvent();
}
}
void TriggerRandomEvent() {
int randomIndex = Random.Range(0, events.Length);
Instantiate(events[randomIndex], transform.position, Quaternion.identity);
Debug.Log("랜덤 이벤트 발생: " + events[randomIndex].name);
}
}
이 코드는 특정 확률에 따라 무작위 이벤트를 발생시킵니다. triggerChance
값을 조정하여 이벤트의 발생 빈도를 설정할 수 있으며, events
배열을 통해 다양한 이벤트를 추가하여 플레이어가 예측하지 못한 상황에 처하게 만들 수 있습니다.