BT5-Dev #107: Tilemap cell 기반 측정 (PD 근본 진단)
PD 근본 진단 (2026-05-08): "절벽 체크 로직이 잘못된 것이 근본원인" + 공중 부유 발생
본 PM 22회+ 가설 누적 부정확 자인. PD 근본 진단 정합 — Raycast 영역 자체 부정확.
정정 (BT107):
1. BT106 y 강제 고정 영역 폐기 (공중 부유 원인)
2. MeasureSafeWalkDistance 영역 = Tilemap cell 기반 재설계:
- GameObject.Find('Level') + 'AutoForeground' → groundTilemaps 영역
- Enemy 발 아래 cell = 시작 cell (Tilemap.WorldToCell)
- 좌·우 연속 Tile 영역 끝 영역 검색 (cell + Vector3Int.left/right)
- HasTileInAnyTilemap 검사 (Level + AutoForeground)
- 마지막 Tile cell center 영역까지 거리 - 0.5m margin
효과:
- Raycast 영역 부정확 영역 폐기 (Tile data 직접 사용)
- Tile cell 단위 정확 영역 측정 → patrol 영역 정확
- 시작 cell 발판 X 시 = 0 반환 (재배치 영역 BT104에서 처리)
- 공중 부유 영역 차단 (BT106 폐기)
This commit is contained in:
parent
589f6ad258
commit
1137583b4b
|
|
@ -166,18 +166,63 @@ namespace Platformer.Mechanics
|
|||
_lastX = transform.position.x;
|
||||
}
|
||||
|
||||
// BT105 — 정확 측정·안전 margin 2.0m (PD 보고 떨어짐 잔존: 보수적 영역으로 절벽 도달 X 보장)
|
||||
// BT107 — Tilemap 영역 cell 기반 측정 (PD 근본 진단: Raycast 영역 자체 부정확)
|
||||
// Enemy 시작 위치 cell → 좌·우 연속 Tile 영역 끝 영역까지 거리 = 안전 patrol 거리
|
||||
float MeasureSafeWalkDistance(float dir)
|
||||
{
|
||||
if (_collider == null) return patrolMaxRange;
|
||||
float groundY = _collider.bounds.min.y + 0.05f;
|
||||
for (float d = 0.1f; d <= patrolMaxRange; d += 0.1f)
|
||||
if (_collider == null) return 0f;
|
||||
|
||||
var groundTilemaps = new System.Collections.Generic.List<UnityEngine.Tilemaps.Tilemap>();
|
||||
var levelGo = GameObject.Find("Level");
|
||||
if (levelGo != null)
|
||||
{
|
||||
Vector2 origin = new Vector2(_startX + dir * d, groundY);
|
||||
RaycastHit2D hit = Physics2D.Raycast(origin, Vector2.down, cliffCheckDepth, groundLayerMask);
|
||||
if (hit.collider == null) return Mathf.Max(0f, d - 2.0f); // BT105: 0.5→2.0m
|
||||
var t = levelGo.GetComponent<UnityEngine.Tilemaps.Tilemap>();
|
||||
if (t != null) groundTilemaps.Add(t);
|
||||
}
|
||||
return patrolMaxRange;
|
||||
var autoFgGo = GameObject.Find("AutoForeground");
|
||||
if (autoFgGo != null)
|
||||
{
|
||||
var t = autoFgGo.GetComponent<UnityEngine.Tilemaps.Tilemap>();
|
||||
if (t != null) groundTilemaps.Add(t);
|
||||
}
|
||||
if (groundTilemaps.Count == 0) return 0f;
|
||||
|
||||
// 시작 cell = Enemy 발 아래 cell
|
||||
Vector3 footPos = new Vector3(_startX, _collider.bounds.min.y - 0.1f, 0f);
|
||||
UnityEngine.Tilemaps.Tilemap startTm = null;
|
||||
Vector3Int startCell = Vector3Int.zero;
|
||||
foreach (var tm in groundTilemaps)
|
||||
{
|
||||
Vector3Int cell = tm.WorldToCell(footPos);
|
||||
if (tm.HasTile(cell))
|
||||
{
|
||||
startTm = tm;
|
||||
startCell = cell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (startTm == null) return 0f;
|
||||
|
||||
// 좌·우 연속 Tile 영역 끝 영역 검색
|
||||
int dirCell = (int)Mathf.Sign(dir);
|
||||
Vector3Int cellIter = startCell;
|
||||
for (int steps = 0; steps < 500; steps++)
|
||||
{
|
||||
Vector3Int nextCell = cellIter + new Vector3Int(dirCell, 0, 0);
|
||||
if (!HasTileInAnyTilemap(groundTilemaps, nextCell)) break;
|
||||
cellIter = nextCell;
|
||||
}
|
||||
|
||||
// 마지막 Tile cell 영역 center 영역까지 거리
|
||||
Vector3 lastTileWorld = startTm.CellToWorld(cellIter) + new Vector3(0.5f, 0f, 0f);
|
||||
float distance = Mathf.Abs(lastTileWorld.x - _startX);
|
||||
return Mathf.Max(0f, distance - 0.5f); // 안전 margin 0.5m (Tile cell 영역 안)
|
||||
}
|
||||
|
||||
static bool HasTileInAnyTilemap(System.Collections.Generic.List<UnityEngine.Tilemaps.Tilemap> tms, Vector3Int cell)
|
||||
{
|
||||
foreach (var tm in tms) if (tm != null && tm.HasTile(cell)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetNextPatrolTarget()
|
||||
|
|
@ -210,15 +255,7 @@ namespace Platformer.Mechanics
|
|||
return;
|
||||
}
|
||||
|
||||
// BT106 — y 강제 고정 (PD 명시 2026-05-08): Enemy 영역 매 frame _startY 영역 영구 위치
|
||||
// 떨어짐 영역 0.1m 이상 발생 시 = 즉시 _startY 복귀 → 떨어짐 영역 영구 차단
|
||||
if (Mathf.Abs(transform.position.y - _startY) > 0.1f)
|
||||
{
|
||||
Vector3 fixedY = new Vector3(transform.position.x, _startY, transform.position.z);
|
||||
transform.position = fixedY;
|
||||
if (_body != null) _body.position = fixedY;
|
||||
if (control != null) control.velocity = new Vector2(control.velocity.x, 0f);
|
||||
}
|
||||
// BT107 — BT106 y 강제 고정 영역 폐기 (PD 보고: 공중 부유 영역 원인)
|
||||
|
||||
// 대기 영역 — control.move.x = 0 + Timer 감소
|
||||
if (_waitTimer > 0f)
|
||||
|
|
|
|||
Loading…
Reference in New Issue