namespace ClientTester.DummyService; public class MapBounds { public float MinX { get; set; } public float MaxX { get; set; } public float MinZ { get; set; } public float MaxZ { get; set; } public MapBounds(float minX, float maxX, float minZ, float maxZ) { MinX = minX; MaxX = maxX; MinZ = minZ; MaxZ = maxZ; } // 위치가 경계 안에 있는지 체크 public bool IsInside(float x, float z) { return x >= MinX && x <= MaxX && z >= MinZ && z <= MaxZ; } // 경계 초과 시 clamp, 벽에 부딪혔으면 true 반환 public bool Clamp(ref float x, ref float z) { bool hit = false; if (x < MinX) { x = MinX; hit = true; } else if (x > MaxX) { x = MaxX; hit = true; } if (z < MinZ) { z = MinZ; hit = true; } else if (z > MaxZ) { z = MaxZ; hit = true; } return hit; } // 현재 위치 기준으로 벽 반대 방향 rotY 계산 (벽 없으면 -1) public int GetRotYAwayFromWall(float x, float z, float margin = 0.5f) { bool atLeft = x <= MinX + margin; bool atRight = x >= MaxX - margin; bool atBottom = z <= MinZ + margin; bool atTop = z >= MaxZ - margin; if (!atLeft && !atRight && !atBottom && !atTop) { return -1; // 벽 근처 아님 } // 벽 반대 방향 벡터 합산 float awayX = 0f, awayZ = 0f; if (atLeft) { awayX += 1f; } if (atRight) { awayX -= 1f; } if (atBottom) { awayZ += 1f; } if (atTop) { awayZ -= 1f; } // 정규화 float len = MathF.Sqrt(awayX * awayX + awayZ * awayZ); awayX /= len; awayZ /= len; // 방향 벡터 → rotY (degree) return ((int)(MathF.Atan2(awayX, awayZ) * 180f / MathF.PI) + 360) % 360; } }