Files
a301_mmo_game_server/ClientTester/EchoClientTester/DummyService/MapBounds.cs

117 lines
2.2 KiB
C#

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;
}
}