Skip to content

karnelian/NetcodeFramework-System-Procedural

Repository files navigation

System-Procedural 맵 생성기

사용법

1. SO 생성

Unity Inspector에서 Create > NetcodeFramework > Procedural 메뉴:

SO 용도
ArenaMapSettings Arena (원형/사각형 열린 공간)
LaneMapSettings Lane (시작→끝 경로 기반)
DungeonMapSettings Dungeon (방+복도 연결)
MapModuleData 모듈 프리팹 메타데이터

2. MapModuleData 설정

필드 설명
Prefab 모듈 프리팹 드래그
Category Ground / Wall / Obstacle / Cover / Hazard / Decoration
GridSize 차지하는 셀 수 (1×1, 3×1 등)
PlacementType FreeRotation / AlignToEdge / AlignToPath / Fixed
FrontDirection 정면 방향 (0,0,0이면 자동 감지)
AllowedRings 배치 가능 영역 (Core/Inner/Middle/Outer)
AllowedZones 배치 가능 Zone (비어있으면 AllowedRings에서 변환)
Weight 등장 확률 가중치
MaxCount 최대 개수 (0=무제한)
MinSpacing 같은 모듈 간 최소 거리 (셀 단위)

3. ArenaMapSettings

Map Shape: Circle / Rectangle
├── Circle: coreRadius, innerRadius, middleRadius, outerRadius
└── Rectangle: mapWidth, mapHeight

Module Pool: [MapModuleData 배열 — 드래그]

Obstacle Strategy: [Flags] PerimeterWall | Cluster | Scatter
├── Scatter: innerDensity, middleDensity, outerDensity (Ring별 밀도)
├── PerimeterWall: wallThickness, wallCategory
└── Cluster: clusterSize, clusterCount, clusterSpread

Placement: moduleMargin, maxRetries, cellSize
Path Validation: enablePathValidation
NavMesh: useRuntimeNavMeshBake

4. LaneMapSettings

Map Size: mapLength (경로 방향), mapWidth (수직 방향)

Lane:
├── laneCount: 레인 수 (1~5)
├── laneWidth: 레인 폭 (월드 유닛)
├── laneCurve: 곡선도 (0=직선, 1=최대)
├── waypointCount: 경로당 웨이포인트 수
└── direction: LeftToRight / RightToLeft / BottomToTop / TopToBottom

endpointRadius: 시작/끝 보호 반경

Module Pool / Strategy / Placement: Arena와 동일
주의: Scatter는 Arena 전용 (Lane에서 사용 시 무시됨)

5. DungeonMapSettings

Map Size: mapWidth, mapHeight

BSP:
├── minRoomSize: 방 최소 크기 (셀 단위)
├── maxRoomSize: 방 최대 크기
├── bspDepth: 분할 깊이 (3~6, 높을수록 방 많음)
└── roomPadding: 리프 대비 방 크기 비율 (0.4~0.9)

Corridor:
├── corridorWidth: 복도 폭 (셀 단위)
└── extraCorridorRate: 추가 루프 비율 (0~0.5)

coreRadius: 방 중앙 보호 반경

Module Pool / Strategy / Placement: Arena와 동일
주의: Scatter는 Arena 전용. Dungeon은 Cluster 사용 권장

6. 씬 설정

  1. 빈 GameObject 생성 → ProceduralMapManager 컴포넌트 추가
  2. Settings 필드에 위에서 만든 SO 드래그
  3. Inspector에서 Generate / Random / Clear 버튼 사용
  4. 또는 메뉴: NetcodeFramework > Procedural > Generate Map Preview

7. 카테고리별 용도

Category 용도 경로 체크 벽 충돌
Ground 바닥 타일 - -
Wall 외벽 (Arena/Lane) / 방 경계 (Dungeon) 안 함 -
Obstacle 내부 장애물
Cover 엄폐물
Hazard 위험 지역
Decoration 장식

8. Generator 직접 사용 (Manager 없이)

// NetcodeFramework Manager 없이도 Generator를 직접 사용 가능
var settings = ScriptableObject.CreateInstance<ArenaMapSettings>();
// ... Inspector에서 설정하거나 코드로 설정 ...

var generator = new ArenaMapGenerator(settings, transform);
generator.Generate(12345);

// 맵 데이터 읽기
var modules = generator.GetPlacedModules();
var zone = generator.GetZoneAt(worldPosition);
bool canPlace = generator.IsPlaceableAt(worldPosition);

9. 런타임 쿼리 API

// 배치된 모듈 목록
IReadOnlyList<PlacedModule> modules = generator.GetPlacedModules();

// 각 모듈의 정보
foreach (var m in modules)
{
    m.Instance;      // GameObject
    m.Data;          // MapModuleData SO
    m.WorldBounds;   // 월드 바운드
    m.Zone;          // MapZone (Center/Inner/Middle/Edge/Corner)
}

// 위치 쿼리
MapZone zone = generator.GetZoneAt(position);  // 이 위치의 Zone
bool inside = generator.IsInsideBounds(position);  // 맵 내부인지
bool placeable = generator.IsPlaceableAt(position);  // 배치 가능한지

10. 새 토폴로지 추가 방법

  1. Data/MyMapSettings.csMapGeneratorSettings 상속
  2. Generators/MyMapGenerator.csIMapGenerator 구현
  3. ProceduralMapManager.cs — switch에 분기 추가
  4. (선택) Zones/MyZoneProvider.csIZoneProvider 구현

11. 새 배치 전략 추가 방법

  1. Strategies/MyStrategy.csIObstacleStrategy 구현
  2. Data/MapShape.csObstaclePlacementStrategy enum에 값 추가
  3. MapGeneratorHelper.GetActiveStrategies() — 분기 추가

12. 경로 검증 API

// 두 지점 간 경로 확인
bool connected = PathValidator.IsPathConnected(posA, posB);

// 맵 전체 4방향 검증
bool valid = PathValidator.Validate(settings, parent);

13. 맵 품질 분석

var metrics = MapMetrics.Analyze(generator.GetPlacedModules(), settings, parent);
Debug.Log($"Quality: {metrics.QualityScore}/100");
Debug.Log($"Density: {metrics.DensityRatio:P1}");
Debug.Log($"Empty: {metrics.EmptyRatio:P1}");
Debug.Log($"PathOK: {metrics.PathAccessible}");

14. Save-Load (시드 기반 재현)

// 저장: 시드만 저장하면 동일 맵 재현 가능
int savedSeed = generator.CurrentSeed;
PlayerPrefs.SetInt("MapSeed", savedSeed);

// 로드: 같은 시드 + 같은 설정 → 100% 동일 맵
generator.Generate(PlayerPrefs.GetInt("MapSeed"));

15. 의존성

  • 필수: com.unity.ai.navigation (NavMesh)
  • 필수: NetcodeFramework (EventBus, MonoSingleton)
  • 선택: Manager 없이 Generator 직접 new() 시 MonoSingleton 불필요

16. 런타임 모듈 배치/제거

// 배치 가능 확인
bool canPlace = generator.CanPlaceModule(position, moduleData);

// 배치
PlacedModule? result = generator.PlaceModuleAt(position, moduleData);
if (result.HasValue)
    Debug.Log($"배치 성공: {result.Value.Instance.name}");

// 제거
bool removed = generator.RemoveModuleAt(position);

17. 전체 API 요약

API 용도
Generate(seed) 맵 생성
Clear() 맵 제거
IsGenerated 생성 여부
CurrentSeed 현재 시드
CellSize 셀 크기
GetSettings() 설정 SO
GetPlacedModules() 배치된 모듈 목록
GroundTileCount Ground 타일 수
IsInsideBounds(pos) 맵 범위 내
IsPlaceableAt(pos) 배치 가능 여부
GetZoneAt(pos) Zone 조회
CanPlaceModule(pos, data) 모듈 배치 가능
PlaceModuleAt(pos, data) 런타임 배치
RemoveModuleAt(pos) 런타임 제거

About

Procedural Map Generator System - 6 topologies (Arena/Lane/Dungeon/OpenField/GridBoard/Track)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages