Map Generator Added

맵 생성기 제작했습니다.
This commit is contained in:
백민승_crow 2026-01-26 18:07:09 +09:00
parent 8e46b58e61
commit 7449deee12
26 changed files with 6228 additions and 1120 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ef8633bbef7424c42aa6f4b54d3e6190
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 41746c5e9fd4cb340bd5a8e1a441b594
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 47c278bcadad24542891f8059255452a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8cc2dd5140f6acd4594c291988ffa85a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f14d701489108ef4aa0c2a723a069b8b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,85 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class MapChunk : MonoBehaviour
{
[Header("Tilemaps")]
[SerializeField] private Tilemap wallTilemap;
[SerializeField] private Tilemap breakableTilemap;
[SerializeField] private Tilemap propsTilemap;
[Header("Procedural Settings")]
[SerializeField] private TileBase[] availablePropTiles;
[Range(0f, 1f)] [SerializeField] private float erosionRate = 0.1f;
[Range(0f, 1f)] [SerializeField] private float propSpawnRate = 0.2f;
public void InitializeChunk(bool isMirrored)
{
if (isMirrored)
{
Vector3 scale = transform.localScale;
scale.x = -1;
transform.localScale = scale;
}
ErodeTerrain();
GenerateProps();
}
public void SpawnEnemies(GameObject[] groundPrefabs, int groundCount, GameObject[] airPrefabs, int airCount)
{
// 추후 팩토리 패턴 적용 예정
}
private void ErodeTerrain()
{
if (breakableTilemap == null) return;
BoundsInt bounds = breakableTilemap.cellBounds;
for (int x = bounds.xMin; x < bounds.xMax; x++)
{
for (int y = bounds.yMin; y < bounds.yMax; y++)
{
Vector3Int pos = new Vector3Int(x, y, 0);
if (breakableTilemap.HasTile(pos))
{
if (Random.value < erosionRate)
{
breakableTilemap.SetTile(pos, null);
}
}
}
}
}
private void GenerateProps()
{
if (propsTilemap == null || availablePropTiles.Length == 0) return;
BoundsInt bounds = breakableTilemap.cellBounds;
for (int x = bounds.xMin; x < bounds.xMax; x++)
{
for (int y = bounds.yMin; y < bounds.yMax; y++)
{
Vector3Int currentPos = new Vector3Int(x, y, 0);
Vector3Int abovePos = new Vector3Int(x, y + 1, 0);
bool hasGround = breakableTilemap.HasTile(currentPos);
bool isAirAbove = !wallTilemap.HasTile(abovePos) && !breakableTilemap.HasTile(abovePos);
if (hasGround && isAirAbove)
{
if (Random.value < propSpawnRate)
{
TileBase randomProp = availablePropTiles[Random.Range(0, availablePropTiles.Length)];
propsTilemap.SetTile(abovePos, randomProp);
}
}
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6e6e97c5e9315644da61b9c55d8a0153

View File

@ -0,0 +1,71 @@
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
[Header("맵 설정용")]
[SerializeField] private GameObject[] mapChunkPrefab;
[SerializeField] private GameObject startChunkPrefab;
[SerializeField] private int mapChunkSize = 14;
private float lateSpawnedChunkLocationY = 0;
[Header("플레이어 설정")]
[SerializeField] private Transform playerTransform;
private Queue<GameObject> chunkQueue = new Queue<GameObject>();
[Header("적 설정")]
[SerializeField] private GameObject[] groundEnemyPrefabs;
[SerializeField] private int groundEnemyCount = 2;
[SerializeField] private GameObject[] airEnemyPrefabs;
[SerializeField] private int airEnemyCount = 1;
private void Start()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
SpawnChunkPrefab();
SpawnChunkPrefab();
SpawnChunkPrefab();
}
private void SpawnChunkPrefab()
{
if (mapChunkPrefab == null) return;
GameObject spawnedChunkObj = chunkQueue.Count < 1 ? Instantiate(startChunkPrefab) : Instantiate(mapChunkPrefab[Random.Range(0, mapChunkPrefab.Length)]);
spawnedChunkObj.transform.position = new Vector2(0, lateSpawnedChunkLocationY);
chunkQueue.Enqueue(spawnedChunkObj);
MapChunk mapChunk = spawnedChunkObj.GetComponent<MapChunk>();
if (mapChunk != null)
{
bool isMirrored = Random.value > 0.5f;
mapChunk.InitializeChunk(isMirrored);
mapChunk.SpawnEnemies(groundEnemyPrefabs, groundEnemyCount, airEnemyPrefabs, airEnemyCount);
}
else
{
Debug.Log("Script 추가하기");
}
lateSpawnedChunkLocationY -= mapChunkSize;
}
public void Update()
{
if (chunkQueue.Count < 3) return;
float middleChunkY = lateSpawnedChunkLocationY + mapChunkSize;
if (playerTransform.position.y <= middleChunkY)
{
RemoveAndSpawnNewChunk();
}
}
private void RemoveAndSpawnNewChunk()
{
GameObject removedChunk = chunkQueue.Dequeue();
Destroy(removedChunk);
SpawnChunkPrefab();
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5e7d23336d894ca408df792e757e12f2

View File

@ -0,0 +1,16 @@
using UnityEngine;
public class MonsterFactory : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 46977ad4134ee5948a3da02e0e6e53d3

View File

@ -772,7 +772,7 @@ PlayerSettings:
qnxGraphicConfPath: qnxGraphicConfPath:
apiCompatibilityLevel: 6 apiCompatibilityLevel: 6
captureStartupLogs: {} captureStartupLogs: {}
activeInputHandler: 1 activeInputHandler: 2
windowsGamepadBackendHint: 0 windowsGamepadBackendHint: 0
cloudProjectId: 04f0f60d-e262-4e2b-85bb-975b3dc2e089 cloudProjectId: 04f0f60d-e262-4e2b-85bb-975b3dc2e089
framebufferDepthMemorylessMode: 0 framebufferDepthMemorylessMode: 0