로크라이크 게임에서 모듈화 코드의 중요성

로크라이크 게임의 핵심은 무작위성, 리플레이성, 예측 불가능한 이벤트에 있습니다. 이 요소들은 플레이어가 매번 새로운 경험을 하게 만들어 주지만, 개발자와 기획자 입장에서는 구현 과정이 쉽지 않은 작업입니다. 특히 유니티에서 로크라이크 게임을 개발할 때 자주 반복되는 기능들을 모듈화하여 재사용 가능한 코드를 제공하는 것이 효율적입니다. 이 글에서는 로크라이크 개발에서 즉시 활용할 수 있는 실용적인 코드 모음과 기능들을 소개해드리겠습니다.

무작위 맵 생성기: 던전 구조를 만드는 기본 코드

로크라이크 게임에서 무작위로 생성되는 맵은 게임의 다양한 경험을 만들어 주는 중요한 요소입니다. 던전 스타일의 맵을 생성하는 데는 다양한 방법이 있지만, 그 중 가장 흔하게 사용하는 알고리즘 중 하나는 “방과 통로 연결” 방식입니다.

예시 코드: 방과 통로를 무작위로 배치하는 맵 생성기

아래 코드는 일정한 범위 내에 무작위로 방을 생성하고, 각 방을 통로로 연결해주는 방식으로 맵을 생성합니다. 이 코드는 던전의 구조를 만드는 데 효과적이며, 사용자가 쉽게 커스터마이징할 수 있도록 모듈화되어 있습니다.

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 배열을 통해 다양한 이벤트를 추가하여 플레이어가 예측하지 못한 상황에 처하게 만들 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다